diff options
Diffstat (limited to 'libs')
444 files changed, 10784 insertions, 5551 deletions
diff --git a/libs/WindowManager/Shell/res/animator/tv_pip_menu_action_button_animator.xml b/libs/WindowManager/Shell/res/animator/tv_window_menu_action_button_animator.xml index 7475abac4695..7475abac4695 100644 --- a/libs/WindowManager/Shell/res/animator/tv_pip_menu_action_button_animator.xml +++ b/libs/WindowManager/Shell/res/animator/tv_window_menu_action_button_animator.xml diff --git a/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon.xml b/libs/WindowManager/Shell/res/color/tv_window_menu_close_icon.xml index ce8640df0093..67467bbc72ae 100644 --- a/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon.xml +++ b/libs/WindowManager/Shell/res/color/tv_window_menu_close_icon.xml @@ -15,5 +15,5 @@ ~ limitations under the License. --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:color="@color/tv_pip_menu_icon_unfocused" /> + <item android:color="@color/tv_window_menu_icon_unfocused" /> </selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/color/tv_pip_menu_icon_bg.xml b/libs/WindowManager/Shell/res/color/tv_window_menu_close_icon_bg.xml index 4f5e63dac5c0..4182bfeefa1b 100644 --- a/libs/WindowManager/Shell/res/color/tv_pip_menu_icon_bg.xml +++ b/libs/WindowManager/Shell/res/color/tv_window_menu_close_icon_bg.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2021 The Android Open Source Project + ~ 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. @@ -16,6 +16,6 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" - android:color="@color/tv_pip_menu_icon_bg_focused" /> - <item android:color="@color/tv_pip_menu_icon_bg_unfocused" /> + android:color="@color/tv_window_menu_close_icon_bg_focused" /> + <item android:color="@color/tv_window_menu_close_icon_bg_unfocused" /> </selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/color/tv_pip_menu_icon.xml b/libs/WindowManager/Shell/res/color/tv_window_menu_icon.xml index 275870450493..45205d2a7138 100644 --- a/libs/WindowManager/Shell/res/color/tv_pip_menu_icon.xml +++ b/libs/WindowManager/Shell/res/color/tv_window_menu_icon.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2021 The Android Open Source Project + ~ 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. @@ -16,8 +16,8 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" - android:color="@color/tv_pip_menu_icon_focused" /> + android:color="@color/tv_window_menu_icon_focused" /> <item android:state_enabled="false" - android:color="@color/tv_pip_menu_icon_disabled" /> - <item android:color="@color/tv_pip_menu_icon_unfocused" /> + android:color="@color/tv_window_menu_icon_disabled" /> + <item android:color="@color/tv_window_menu_icon_unfocused" /> </selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon_bg.xml b/libs/WindowManager/Shell/res/color/tv_window_menu_icon_bg.xml index 6cbf66f00df7..1bd26e1d6583 100644 --- a/libs/WindowManager/Shell/res/color/tv_pip_menu_close_icon_bg.xml +++ b/libs/WindowManager/Shell/res/color/tv_window_menu_icon_bg.xml @@ -16,6 +16,6 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" - android:color="@color/tv_pip_menu_close_icon_bg_focused" /> - <item android:color="@color/tv_pip_menu_close_icon_bg_unfocused" /> + android:color="@color/tv_window_menu_icon_bg_focused" /> + <item android:color="@color/tv_window_menu_icon_bg_unfocused" /> </selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/tv_pip_button_bg.xml b/libs/WindowManager/Shell/res/drawable/tv_pip_button_bg.xml deleted file mode 100644 index 1938f4562e97..000000000000 --- a/libs/WindowManager/Shell/res/drawable/tv_pip_button_bg.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:radius="@dimen/pip_menu_button_radius" /> - <solid android:color="@color/tv_pip_menu_icon_bg" /> -</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml b/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml index 846fdb3e8a58..7085a2c72c86 100644 --- a/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml +++ b/libs/WindowManager/Shell/res/drawable/tv_pip_menu_border.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> <selector xmlns:android="http://schemas.android.com/apk/res/android" - android:exitFadeDuration="@integer/pip_menu_fade_animation_duration"> + android:exitFadeDuration="@integer/tv_window_menu_fade_animation_duration"> <item android:state_activated="true"> <shape android:shape="rectangle"> <corners android:radius="@dimen/pip_menu_border_corner_radius" /> diff --git a/libs/WindowManager/Shell/res/drawable/tv_split_menu_ic_focus.xml b/libs/WindowManager/Shell/res/drawable/tv_split_menu_ic_focus.xml new file mode 100644 index 000000000000..a348b148afb4 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/tv_split_menu_ic_focus.xml @@ -0,0 +1,26 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="@dimen/tv_window_menu_icon_size" + android:height="@dimen/tv_window_menu_icon_size" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + + <path + android:fillColor="#FFFFFF" + android:pathData="M17,4h3c1.1,0 2,0.9 2,2v2h-2L20,6h-3L17,4zM4,8L4,6h3L7,4L4,4c-1.1,0 -2,0.9 -2,2v2h2zM20,16v2h-3v2h3c1.1,0 2,-0.9 2,-2v-2h-2zM7,18L4,18v-2L2,16v2c0,1.1 0.9,2 2,2h3v-2zM18,8L6,8v8h12L18,8z"/> +</vector> diff --git a/libs/WindowManager/Shell/res/drawable/tv_split_menu_ic_swap.xml b/libs/WindowManager/Shell/res/drawable/tv_split_menu_ic_swap.xml new file mode 100644 index 000000000000..c5d54c5fa4f2 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/tv_split_menu_ic_swap.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="@dimen/tv_window_menu_icon_size" + android:height="@dimen/tv_window_menu_icon_size" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFF" + android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z"/> +</vector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/tv_window_button_bg.xml b/libs/WindowManager/Shell/res/drawable/tv_window_button_bg.xml new file mode 100644 index 000000000000..2dba37daf059 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/tv_window_button_bg.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="@dimen/tv_window_menu_button_radius" /> + <solid android:color="@color/tv_window_menu_icon_bg" /> +</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml index 7a3ee23d8cdc..afd3aac9b461 100644 --- a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml +++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml @@ -16,92 +16,98 @@ --> <!-- Layout for TvPipMenuView --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/tv_pip_menu" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="center|top"> + android:id="@+id/tv_pip_menu" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center|top"> <!-- Matches the PiP app content --> - <View + <FrameLayout android:id="@+id/tv_pip" android:layout_width="0dp" android:layout_height="0dp" - android:alpha="0" - android:background="@color/tv_pip_menu_background" android:layout_marginTop="@dimen/pip_menu_outer_space" android:layout_marginStart="@dimen/pip_menu_outer_space" - android:layout_marginEnd="@dimen/pip_menu_outer_space"/> - - <ScrollView - android:id="@+id/tv_pip_menu_scroll" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignTop="@+id/tv_pip" - android:layout_alignStart="@+id/tv_pip" - android:layout_alignEnd="@+id/tv_pip" - android:layout_alignBottom="@+id/tv_pip" - android:scrollbars="none" - android:visibility="gone"/> - - <HorizontalScrollView - android:id="@+id/tv_pip_menu_horizontal_scroll" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignTop="@+id/tv_pip" - android:layout_alignStart="@+id/tv_pip" - android:layout_alignEnd="@+id/tv_pip" - android:layout_alignBottom="@+id/tv_pip" - android:scrollbars="none"> - - <LinearLayout - android:id="@+id/tv_pip_menu_action_buttons" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:alpha="0"> + android:layout_marginEnd="@dimen/pip_menu_outer_space"> - <Space - android:layout_width="@dimen/pip_menu_button_wrapper_margin" - android:layout_height="@dimen/pip_menu_button_wrapper_margin"/> - - <com.android.wm.shell.pip.tv.TvPipMenuActionButton - android:id="@+id/tv_pip_menu_fullscreen_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@drawable/pip_ic_fullscreen_white" - android:text="@string/pip_fullscreen" /> + <View + android:id="@+id/tv_pip_menu_background" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/tv_pip_menu_background" + android:alpha="0"/> - <com.android.wm.shell.pip.tv.TvPipMenuActionButton - android:id="@+id/tv_pip_menu_close_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@drawable/pip_ic_close_white" - android:text="@string/pip_close" /> + <View + android:id="@+id/tv_pip_menu_dim_layer" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/tv_pip_menu_dim_layer" + android:alpha="0"/> - <!-- More TvPipMenuActionButtons may be added here at runtime. --> + <ScrollView + android:id="@+id/tv_pip_menu_scroll" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scrollbars="none" + android:visibility="gone"/> - <com.android.wm.shell.pip.tv.TvPipMenuActionButton - android:id="@+id/tv_pip_menu_move_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@drawable/pip_ic_move_white" - android:text="@string/pip_move" /> + <HorizontalScrollView + android:id="@+id/tv_pip_menu_horizontal_scroll" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scrollbars="none"> - <com.android.wm.shell.pip.tv.TvPipMenuActionButton - android:id="@+id/tv_pip_menu_expand_button" + <LinearLayout + android:id="@+id/tv_pip_menu_action_buttons" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/pip_ic_collapse" - android:visibility="gone" - android:text="@string/pip_collapse" /> - - <Space - android:layout_width="@dimen/pip_menu_button_wrapper_margin" - android:layout_height="@dimen/pip_menu_button_wrapper_margin"/> - - </LinearLayout> - </HorizontalScrollView> + android:orientation="horizontal" + android:alpha="0"> + + <Space + android:layout_width="@dimen/pip_menu_button_wrapper_margin" + android:layout_height="@dimen/pip_menu_button_wrapper_margin"/> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_pip_menu_fullscreen_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/pip_ic_fullscreen_white" + android:text="@string/pip_fullscreen" /> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_pip_menu_close_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/pip_ic_close_white" + android:text="@string/pip_close" /> + + <!-- More TvWindowMenuActionButtons may be added here at runtime. --> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_pip_menu_move_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/pip_ic_move_white" + android:text="@string/pip_move" /> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_pip_menu_expand_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/pip_ic_collapse" + android:visibility="gone" + android:text="@string/pip_collapse" /> + + <Space + android:layout_width="@dimen/pip_menu_button_wrapper_margin" + android:layout_height="@dimen/pip_menu_button_wrapper_margin"/> + + </LinearLayout> + </HorizontalScrollView> + </FrameLayout> + <!-- Frame around the content, just overlapping the corners to make them round --> <View android:id="@+id/tv_pip_border" android:layout_width="0dp" @@ -111,6 +117,7 @@ android:layout_marginEnd="@dimen/pip_menu_outer_space_frame" android:background="@drawable/tv_pip_menu_border"/> + <!-- Temporarily extending the background to show an edu text hint for opening the menu --> <FrameLayout android:id="@+id/tv_pip_menu_edu_text_container" android:layout_width="match_parent" @@ -128,6 +135,7 @@ android:layout_height="@dimen/pip_menu_edu_text_view_height" android:layout_gravity="bottom|center" android:gravity="center" + android:clickable="false" android:paddingBottom="@dimen/pip_menu_border_width" android:text="@string/pip_edu_text" android:singleLine="true" @@ -137,6 +145,7 @@ android:textAppearance="@style/TvPipEduText"/> </FrameLayout> + <!-- Frame around the PiP content + edu text hint - used to highlight open menu --> <View android:id="@+id/tv_pip_menu_frame" android:layout_width="match_parent" @@ -144,6 +153,17 @@ android:layout_margin="@dimen/pip_menu_outer_space_frame" android:background="@drawable/tv_pip_menu_border"/> + <!-- Move menu --> + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_pip_menu_done_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_centerVertical="true" + android:src="@drawable/pip_ic_close_white" + android:visibility="gone" + android:text="@string/a11y_action_pip_move_done" /> + <ImageView android:id="@+id/tv_pip_menu_arrow_up" android:layout_width="@dimen/pip_menu_arrow_size" @@ -151,6 +171,7 @@ android:layout_centerHorizontal="true" android:layout_alignParentTop="true" android:alpha="0" + android:contentDescription="@string/a11y_action_pip_move_up" android:elevation="@dimen/pip_menu_arrow_elevation" android:src="@drawable/pip_ic_move_up" /> @@ -161,6 +182,7 @@ android:layout_centerVertical="true" android:layout_alignParentRight="true" android:alpha="0" + android:contentDescription="@string/a11y_action_pip_move_right" android:elevation="@dimen/pip_menu_arrow_elevation" android:src="@drawable/pip_ic_move_right" /> @@ -171,6 +193,7 @@ android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:alpha="0" + android:contentDescription="@string/a11y_action_pip_move_down" android:elevation="@dimen/pip_menu_arrow_elevation" android:src="@drawable/pip_ic_move_down" /> @@ -181,6 +204,7 @@ android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:alpha="0" + android:contentDescription="@string/a11y_action_pip_move_left" android:elevation="@dimen/pip_menu_arrow_elevation" android:src="@drawable/pip_ic_move_left" /> </RelativeLayout> diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml deleted file mode 100644 index db96d8de4094..000000000000 --- a/libs/WindowManager/Shell/res/layout/tv_pip_menu_action_button.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<!-- Layout for TvPipMenuActionButton --> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/button" - android:layout_width="@dimen/pip_menu_button_size" - android:layout_height="@dimen/pip_menu_button_size" - android:padding="@dimen/pip_menu_button_margin" - android:stateListAnimator="@animator/tv_pip_menu_action_button_animator" - android:focusable="true"> - - <View android:id="@+id/background" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center" - android:duplicateParentState="true" - android:background="@drawable/tv_pip_button_bg"/> - - <ImageView android:id="@+id/icon" - android:layout_width="@dimen/pip_menu_icon_size" - android:layout_height="@dimen/pip_menu_icon_size" - android:layout_gravity="center" - android:duplicateParentState="true" - android:tint="@color/tv_pip_menu_icon" /> -</FrameLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/tv_split_menu_view.xml b/libs/WindowManager/Shell/res/layout/tv_split_menu_view.xml new file mode 100644 index 000000000000..e0fa59c9f157 --- /dev/null +++ b/libs/WindowManager/Shell/res/layout/tv_split_menu_view.xml @@ -0,0 +1,125 @@ +<!-- + ~ 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. + --> +<!-- Layout for TvSplitMenuView --> +<com.android.wm.shell.splitscreen.tv.TvSplitMenuView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="match_parent" + android:layout_width="match_parent"> + + <LinearLayout + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center"> + + <LinearLayout + android:id="@+id/tv_split_main_menu" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="match_parent" + android:orientation="vertical" + android:gravity="center"> + + <Space + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center"> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_split_main_menu_focus_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/tv_split_menu_ic_focus" /> + + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center"> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_split_main_menu_close_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/pip_ic_close_white" /> + + </LinearLayout> + + </LinearLayout> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_split_menu_swap_stages" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/tv_split_menu_ic_swap" /> + + <LinearLayout + android:id="@+id/tv_split_side_menu" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="match_parent" + android:orientation="vertical" + android:gravity="center"> + + <Space + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center"> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_split_side_menu_focus_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/tv_split_menu_ic_focus" /> + + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center"> + + <com.android.wm.shell.common.TvWindowMenuActionButton + android:id="@+id/tv_split_side_menu_close_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/pip_ic_close_white" /> + + </LinearLayout> + + </LinearLayout> + + </LinearLayout> +</com.android.wm.shell.splitscreen.tv.TvSplitMenuView> diff --git a/libs/WindowManager/Shell/res/layout/tv_window_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/tv_window_menu_action_button.xml new file mode 100644 index 000000000000..c4dbd39c729a --- /dev/null +++ b/libs/WindowManager/Shell/res/layout/tv_window_menu_action_button.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<!-- Layout for TvWindowMenuActionButton --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/button" + android:layout_width="@dimen/tv_window_menu_button_size" + android:layout_height="@dimen/tv_window_menu_button_size" + android:padding="@dimen/tv_window_menu_button_margin" + android:stateListAnimator="@animator/tv_window_menu_action_button_animator" + android:focusable="true"> + + <View android:id="@+id/background" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:duplicateParentState="true" + android:background="@drawable/tv_window_button_bg"/> + + <ImageView android:id="@+id/icon" + android:layout_width="@dimen/tv_window_menu_icon_size" + android:layout_height="@dimen/tv_window_menu_icon_size" + android:layout_gravity="center" + android:duplicateParentState="true" + android:tint="@color/tv_window_menu_icon" /> +</FrameLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 2476f65c7e5b..36c24c1b6b08 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Instellings"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Gaan by verdeelde skerm in"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Kieslys"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Prent-in-prent-kieslys"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in beeld-in-beeld"</string> <string name="pip_notification_message" msgid="8854051911700302620">"As jy nie wil hê dat <xliff:g id="NAME">%s</xliff:g> hierdie kenmerk moet gebruik nie, tik om instellings oop te maak en skakel dit af."</string> <string name="pip_play" msgid="3496151081459417097">"Speel"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skermverdeler"</string> + <string name="divider_title" msgid="5482989479865361192">"Skermverdeler"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Volskerm links"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Links 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Links 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Bestuur"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Borrel is toegemaak."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tik om hierdie program te herbegin en maak volskerm oop."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tik om hierdie program te herbegin vir ’n beter aansig."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerakwessies?\nTik om aan te pas"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sommige programme werk beter in portret"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Probeer een van hierdie opsies om jou spasie ten beste te benut"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Draai jou toestel om dit volskerm te maak"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dubbeltik langs ’n program om dit te herposisioneer"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Sien en doen meer"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Sleep ’n ander program in vir verdeelde skerm"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dubbeltik buite ’n program om dit te herposisioneer"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Het dit"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vou uit vir meer inligting."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeer"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Maak klein"</string> + <string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-af/strings_tv.xml b/libs/WindowManager/Shell/res/values-af/strings_tv.xml index c87bec093cca..6187ea46769c 100644 --- a/libs/WindowManager/Shell/res/values-af/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-af/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Beeld-in-beeld"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Titellose program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Maak PIP toe"</string> + <string name="pip_close" msgid="2955969519031223530">"Maak toe"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Volskerm"</string> - <string name="pip_move" msgid="1544227837964635439">"Skuif PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Vou PIP uit"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Vou PIP in"</string> + <string name="pip_move" msgid="158770205886688553">"Skuif"</string> + <string name="pip_expand" msgid="1051966011679297308">"Vou uit"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Vou in"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Dubbeldruk "<annotation icon="home_icon">" TUIS "</annotation>" vir kontroles"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Prent-in-prent-kieslys"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Skuif links"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Skuif regs"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Skuif op"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Skuif af"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Klaar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index f0c391cd6b99..dff8f3fb2677 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ቅንብሮች"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"የተከፈለ ማያ ገጽን አስገባ"</string> <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_play" msgid="3496151081459417097">"አጫውት"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"የተከፈለ የማያ ገጽ ከፋይ"</string> + <string name="divider_title" msgid="5482989479865361192">"የተከፈለ የማያ ገጽ ከፋይ"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"አንዳንድ መተግበሪያዎች በቁም ፎቶ ውስጥ በተሻለ ሁኔታ ይሰራሉ"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ቦታዎን በአግባቡ ለመጠቀም ከእነዚህ አማራጮች ውስጥ አንዱን ይሞክሩ"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ወደ የሙሉ ገጽ ዕይታ ለመሄድ መሣሪያዎን ያሽከርክሩት"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ቦታውን ለመቀየር ከመተግበሪያው ቀጥሎ ላይ ሁለቴ መታ ያድርጉ"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ተጨማሪ ይመልከቱ እና ያድርጉ"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ለተከፈለ ማያ ገጽ ሌላ መተግበሪያ ይጎትቱ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"አስፋ"</string> + <string name="minimize_button_text" msgid="271592547935841753">"አሳንስ"</string> + <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-am/strings_tv.xml b/libs/WindowManager/Shell/res/values-am/strings_tv.xml index d23353858de6..74ce49ef078e 100644 --- a/libs/WindowManager/Shell/res/values-am/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-am/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ስዕል-ላይ-ስዕል"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ርዕስ የሌለው ፕሮግራም)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIPን ዝጋ"</string> + <string name="pip_close" msgid="2955969519031223530">"ዝጋ"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ሙሉ ማያ ገጽ"</string> - <string name="pip_move" msgid="1544227837964635439">"ፒአይፒ ውሰድ"</string> - <string name="pip_expand" msgid="7605396312689038178">"ፒአይፒን ዘርጋ"</string> - <string name="pip_collapse" msgid="5732233773786896094">"ፒአይፒን ሰብስብ"</string> + <string name="pip_move" msgid="158770205886688553">"ውሰድ"</string> + <string name="pip_expand" msgid="1051966011679297308">"ዘርጋ"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ሰብስብ"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ለመቆጣጠሪያዎች "<annotation icon="home_icon">"መነሻ"</annotation>"ን ሁለቴ ይጫኑ"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"የስዕል-ላይ-ስዕል ምናሌ።"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ወደ ግራ ውሰድ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ወደ ቀኝ ውሰድ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ወደ ላይ ውሰድ"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ወደ ታች ውሰድ"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ተጠናቅቋል"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index aa4b3b704110..fa9d2c24dd33 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"الإعدادات"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"الدخول في وضع تقسيم الشاشة"</string> <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_play" msgid="3496151081459417097">"تشغيل"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"أداة تقسيم الشاشة"</string> + <string name="divider_title" msgid="5482989479865361192">"أداة تقسيم الشاشة"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"عرض النافذة اليسرى بملء الشاشة"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ضبط حجم النافذة اليسرى ليكون ٧٠%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"تعمل بعض التطبيقات على أكمل وجه في الشاشات العمودية"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"جرِّب تنفيذ أحد هذه الخيارات للاستفادة من مساحتك إلى أقصى حد."</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"قم بتدوير الشاشة للانتقال إلى وضع ملء الشاشة."</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"انقر مرتين بجانب التطبيق لتغيير موضعه."</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"استخدام تطبيقات متعدّدة في وقت واحد"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"اسحب تطبيقًا آخر لاستخدام وضع تقسيم الشاشة."</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> + <string name="maximize_button_text" msgid="1650859196290301963">"تكبير"</string> + <string name="minimize_button_text" msgid="271592547935841753">"تصغير"</string> + <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml index a1ceda5fc987..9c195a7386a9 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"نافذة ضمن النافذة"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ليس هناك عنوان للبرنامج)"</string> - <string name="pip_close" msgid="9135220303720555525">"إغلاق PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"إغلاق"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ملء الشاشة"</string> - <string name="pip_move" msgid="1544227837964635439">"نقل نافذة داخل النافذة (PIP)"</string> - <string name="pip_expand" msgid="7605396312689038178">"توسيع نافذة داخل النافذة (PIP)"</string> - <string name="pip_collapse" msgid="5732233773786896094">"تصغير نافذة داخل النافذة (PIP)"</string> + <string name="pip_move" msgid="158770205886688553">"نقل"</string> + <string name="pip_expand" msgid="1051966011679297308">"توسيع"</string> + <string name="pip_collapse" msgid="3903295106641385962">"تصغير"</string> <string name="pip_edu_text" msgid="3672999496647508701">" انقر مرتين على "<annotation icon="home_icon">" الصفحة الرئيسية "</annotation>" للوصول لعناصر التحكم."</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"قائمة نافذة ضمن النافذة"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"نقل لليسار"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"نقل لليمين"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"نقل للأعلى"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"نقل للأسفل"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"تمّ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 985d3b9b96fd..039b7e2dafcc 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ছেটিং"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"বিভাজিত স্ক্ৰীন ম’ডলৈ যাওক"</string> <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_play" msgid="3496151081459417097">"প্লে কৰক"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"স্প্লিট স্ক্ৰীনৰ বিভাজক"</string> + <string name="divider_title" msgid="5482989479865361192">"বিভাজিত স্ক্ৰীনৰ বিভাজক"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"বাওঁফালৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"বাওঁফালৰ স্ক্ৰীণখন ৭০% কৰক"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"বাওঁফালৰ স্ক্ৰীণখন ৫০% কৰক"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"এপ্টো ৰিষ্টাৰ্ট কৰিবলৈ আৰু পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ টিপক।"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"কিছুমান এপে প’ৰ্ট্ৰেইট ম’ডত বেছি ভালকৈ কাম কৰে"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"আপোনাৰ spaceৰ পৰা পাৰ্যমানে উপকৃত হ’বলৈ ইয়াৰে এটা বিকল্প চেষ্টা কৰি চাওক"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"পূৰ্ণ স্ক্ৰীনলৈ যাবলৈ আপোনাৰ ডিভাইচটো ঘূৰাওক"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"এপ্টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ কাষত দুবাৰ টিপক"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"চাওক আৰু অধিক কৰক"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"বিভাজিত স্ক্ৰীনৰ বাবে অন্য এটা এপ্ টানি আনি এৰক"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string> + <string name="minimize_button_text" msgid="271592547935841753">"মিনিমাইজ কৰক"</string> + <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-as/strings_tv.xml b/libs/WindowManager/Shell/res/values-as/strings_tv.xml index 8d7bd9f6a27e..816b5b1c79dc 100644 --- a/libs/WindowManager/Shell/res/values-as/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-as/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"চিত্ৰৰ ভিতৰত চিত্ৰ"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(শিৰোনামবিহীন কাৰ্যক্ৰম)"</string> - <string name="pip_close" msgid="9135220303720555525">"পিপ বন্ধ কৰক"</string> + <string name="pip_close" msgid="2955969519031223530">"বন্ধ কৰক"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"সম্পূৰ্ণ স্ক্ৰীন"</string> - <string name="pip_move" msgid="1544227837964635439">"পিপ স্থানান্তৰ কৰক"</string> - <string name="pip_expand" msgid="7605396312689038178">"পিপ বিস্তাৰ কৰক"</string> - <string name="pip_collapse" msgid="5732233773786896094">"পিপ সংকোচন কৰক"</string> + <string name="pip_move" msgid="158770205886688553">"স্থানান্তৰ কৰক"</string> + <string name="pip_expand" msgid="1051966011679297308">"বিস্তাৰ কৰক"</string> + <string name="pip_collapse" msgid="3903295106641385962">"সংকোচন কৰক"</string> <string name="pip_edu_text" msgid="3672999496647508701">" নিয়ন্ত্ৰণৰ বাবে "<annotation icon="home_icon">" গৃহপৃষ্ঠা "</annotation>" বুটামত দুবাৰ হেঁচক"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"চিত্ৰৰ ভিতৰৰ চিত্ৰ মেনু।"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"বাওঁফাললৈ নিয়ক"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"সোঁফাললৈ নিয়ক"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ওপৰলৈ নিয়ক"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"তললৈ নিয়ক"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"হ’ল"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 8cd9b7a635ab..36229187fa8b 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana daxil olun"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Şəkildə Şəkil Menyusu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> şəkil içində şəkildədir"</string> <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> tətbiqinin bu funksiyadan istifadə etməyini istəmirsinizsə, ayarları açmaq və deaktiv etmək üçün klikləyin."</string> <string name="pip_play" msgid="3496151081459417097">"Oxudun"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Tətbiq ikinci ekranda işləməyə bilər."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcısı"</string> + <string name="divider_title" msgid="5482989479865361192">"Bölünmüş ekran ayırıcısı"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Sol tam ekran"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Sol 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sol 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün toxunun."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toxunaraq bu tətbiqi yenidən başladın ki, daha görüntü əldə edəsiniz."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera problemi var?\nBərpa etmək üçün toxunun"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Bəzi tətbiqlər portret rejimində daha yaxşı işləyir"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Məkanınızdan maksimum yararlanmaq üçün bu seçimlərdən birini sınayın"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Tam ekrana keçmək üçün cihazınızı fırladın"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tətbiqin yerini dəyişmək üçün yanına iki dəfə toxunun"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ardını görün və edin"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Bölünmüş ekrandan istifadə etmək üçün başqa tətbiqi sürüşdürüb gətirin"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tətbiqin yerini dəyişmək üçün kənarına iki dəfə toxunun"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ətraflı məlumat üçün genişləndirin."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Böyüdün"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Kiçildin"</string> + <string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-az/strings_tv.xml b/libs/WindowManager/Shell/res/values-az/strings_tv.xml index 87c46fa41a01..ccb7a7069ad8 100644 --- a/libs/WindowManager/Shell/res/values-az/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-az/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Şəkil-içində-Şəkil"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Başlıqsız proqram)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP bağlayın"</string> + <string name="pip_close" msgid="2955969519031223530">"Bağlayın"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Tam ekran"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP tətbiq edin"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP-ni genişləndirin"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP-ni yığcamlaşdırın"</string> + <string name="pip_move" msgid="158770205886688553">"Köçürün"</string> + <string name="pip_expand" msgid="1051966011679297308">"Genişləndirin"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Yığcamlaşdırın"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Nizamlayıcılar üçün "<annotation icon="home_icon">" ƏSAS SƏHİFƏ "</annotation>" süçimini iki dəfə basın"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Şəkildə şəkil menyusu."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Sola köçürün"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Sağa köçürün"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Yuxarı köçürün"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Aşağı köçürün"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Hazırdır"</string> </resources> 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 49524c608543..e65268a280b6 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Podešavanja"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Uđi na podeljeni ekran"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meni slike u slici."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string> <string name="pip_play" msgid="3496151081459417097">"Pusti"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdelnik podeljenog ekrana"</string> + <string name="divider_title" msgid="5482989479865361192">"Razdelnik podeljenog ekrana"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Režim celog ekrana za levi ekran"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi ekran 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Neke aplikacije najbolje funkcionišu u uspravnom režimu"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Isprobajte jednu od ovih opcija da biste na najbolji način iskoristili prostor"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotirajte uređaj za prikaz preko celog ekrana"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da biste promenili njenu poziciju"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vidite i uradite više"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Prevucite drugu aplikaciju da biste koristili podeljeni ekran"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste promenili njenu poziciju"</string> <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="maximize_button_text" msgid="1650859196290301963">"Uvećajte"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Umanjite"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml index c87f30611a07..51a1262b1de7 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string> - <string name="pip_close" msgid="9135220303720555525">"Zatvori PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Ceo ekran"</string> - <string name="pip_move" msgid="1544227837964635439">"Premesti sliku u slici"</string> - <string name="pip_expand" msgid="7605396312689038178">"Proširi sliku u slici"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Skupi sliku u slici"</string> + <string name="pip_move" msgid="158770205886688553">"Premesti"</string> + <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Skupi"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" HOME "</annotation>" za kontrole"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni Slika u slici."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomerite nalevo"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomerite nadesno"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomerite nagore"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomerite nadole"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 1767e0d66241..31fcc171060b 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Налады"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Падзяліць экран"</string> <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_play" msgid="3496151081459417097">"Прайграць"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Раздзяляльнік падзеленага экрана"</string> + <string name="divider_title" msgid="5482989479865361192">"Раздзяляльнік падзеленага экрана"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Некаторыя праграмы лепш за ўсё працуюць у кніжнай арыентацыі"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Каб эфектыўна выкарыстоўваць прастору, паспрабуйце адзін з гэтых варыянтаў"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Каб перайсці ў поўнаэкранны рэжым, павярніце прыладу"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Двойчы націсніце побач з праграмай, каб перамясціць яе"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Адначасова выконвайце розныя задачы"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Перацягніце іншую праграму, каб выкарыстоўваць падзелены экран"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Разгарнуць"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Згарнуць"</string> + <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-be/strings_tv.xml b/libs/WindowManager/Shell/res/values-be/strings_tv.xml index 3566bc372820..15a353c649d6 100644 --- a/libs/WindowManager/Shell/res/values-be/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-be/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Відарыс у відарысе"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Праграма без назвы)"</string> - <string name="pip_close" msgid="9135220303720555525">"Закрыць PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Закрыць"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Поўнаэкранны рэжым"</string> - <string name="pip_move" msgid="1544227837964635439">"Перамясціць PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Разгарнуць відарыс у відарысе"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Згарнуць відарыс у відарысе"</string> + <string name="pip_move" msgid="158770205886688553">"Перамясціць"</string> + <string name="pip_expand" msgid="1051966011679297308">"Разгарнуць"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Згарнуць"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Двойчы націсніце "<annotation icon="home_icon">" ГАЛОЎНЫ ЭКРАН "</annotation>" для пераходу ў налады"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню рэжыму \"Відарыс у відарысе\"."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Перамясціць улева"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Перамясціць управа"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Перамясціць уверх"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Перамясціць уніз"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Гатова"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index c22fb86a4d4d..0944d216dd0f 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Преминаване към разделен екран"</string> <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_play" msgid="3496151081459417097">"Пускане"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Разделител в режима за разделен екран"</string> + <string name="divider_title" msgid="5482989479865361192">"Разделител в режима за разделен екран"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Докоснете, за да рестартирате това приложение в режим на цял екран."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Някои приложения работят най-добре във вертикален режим"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Изпробвайте една от следните опции, за да се възползвате максимално от мястото на екрана"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Завъртете екрана си, за да преминете в режим на цял екран"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Докоснете два пъти дадено приложение, за да промените позицията му"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Преглеждайте и правете повече неща"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Преместете друго приложение с плъзгане, за да преминете в режим за разделен екран"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Увеличаване"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Намаляване"</string> + <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml index 91049fd2cf02..2b27a6927077 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Картина в картината"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програма без заглавие)"</string> - <string name="pip_close" msgid="9135220303720555525">"Затваряне на PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Затваряне"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Цял екран"</string> - <string name="pip_move" msgid="1544227837964635439">"„Картина в картина“: Преместв."</string> - <string name="pip_expand" msgid="7605396312689038178">"Разгъване на прозореца за PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Свиване на прозореца за PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Преместване"</string> + <string name="pip_expand" msgid="1051966011679297308">"Разгъване"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Свиване"</string> <string name="pip_edu_text" msgid="3672999496647508701">" За достъп до контролите натиснете 2 пъти "<annotation icon="home_icon">"НАЧАЛО"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню за функцията „Картина в картината“."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Преместване наляво"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Преместване надясно"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Преместване нагоре"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Преместване надолу"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index c0944e0584e6..87eb9ff0e4f7 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"সেটিংস"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"\'স্প্লিট স্ক্রিন\' মোড চালু করুন"</string> <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_play" msgid="3496151081459417097">"চালান"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"বিভক্ত-স্ক্রিন বিভাজক"</string> + <string name="divider_title" msgid="5482989479865361192">"স্প্লিট স্ক্রিন বিভাজক"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"বাঁ দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"৭০% বাকি আছে"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"৫০% বাকি আছে"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও \'ফুল-স্ক্রিন\' মোড ব্যবহার করুন।"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"কিছু অ্যাপ \'পোর্ট্রেট\' মোডে সবচেয়ে ভাল কাজ করে"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"আপনার স্পেস সবচেয়ে ভালভাবে কাজে লাগাতে এইসব বিকল্পের মধ্যে কোনও একটি ব্যবহার করে দেখুন"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"\'ফুল স্ক্রিন\' মোডে যেতে ডিভাইস ঘোরান"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"কোনও অ্যাপের পাশে ডবল ট্যাপ করে সেটির জায়গা পরিবর্তন করুন"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"দেখুন ও আরও অনেক কিছু করুন"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"স্প্লিট স্ক্রিনের জন্য অন্য অ্যাপে টেনে আনুন"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"বড় করুন"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ছোট করুন"</string> + <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml index 792708d128a5..23c8ffabeede 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ছবির-মধ্যে-ছবি"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(শিরোনামহীন প্রোগ্রাম)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP বন্ধ করুন"</string> + <string name="pip_close" msgid="2955969519031223530">"বন্ধ করুন"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"পূর্ণ স্ক্রিন"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP সরান"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP বড় করুন"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP আড়াল করুন"</string> + <string name="pip_move" msgid="158770205886688553">"সরান"</string> + <string name="pip_expand" msgid="1051966011679297308">"বড় করুন"</string> + <string name="pip_collapse" msgid="3903295106641385962">"আড়াল করুন"</string> <string name="pip_edu_text" msgid="3672999496647508701">" কন্ট্রোলের জন্য "<annotation icon="home_icon">" হোম "</annotation>" বোতামে ডবল প্রেস করুন"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ছবির-মধ্যে-ছবি মেনু।"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"বাঁদিকে সরান"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ডানদিকে সরান"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"উপরে তুলুন"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"নিচে নামান"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"হয়ে গেছে"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index ae01c641cc43..01463c242682 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvori podijeljeni ekran"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meni načina rada slike u slici"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je u načinu priakza Slika u slici"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string> <string name="pip_play" msgid="3496151081459417097">"Reproduciraj"</string> @@ -35,7 +36,8 @@ <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplikacija ne podržava dijeljenje ekrana."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće raditi na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> - <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik ekrana"</string> + <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog ekrana"</string> + <string name="divider_title" msgid="5482989479865361192">"Razdjelnik podijeljenog ekrana"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lijevo cijeli ekran"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Lijevo 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevo 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da ponovo pokrenete ovu aplikaciju radi boljeg prikaza."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s kamerom?\nDodirnite da ponovo namjestite"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Određene aplikacije najbolje funkcioniraju u uspravnom načinu rada"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Isprobajte jednu od ovih opcija da maksimalno iskoristite prostor"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zarotirajte uređaj da aktivirate prikaz preko cijelog ekrana"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da promijenite njen položaj"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Pogledajte i učinite više"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Prevucite još jednu aplikaciju za podijeljeni ekran"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da promijenite njen položaj"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Razumijem"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za više informacija."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziranje"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimiziranje"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml index b7f0dca1b5a5..443fd620fd65 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string> - <string name="pip_close" msgid="9135220303720555525">"Zatvori sliku u slici"</string> + <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Cijeli ekran"</string> - <string name="pip_move" msgid="1544227837964635439">"Pokreni sliku u slici"</string> - <string name="pip_expand" msgid="7605396312689038178">"Proširi sliku u slici"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Suzi sliku u slici"</string> + <string name="pip_move" msgid="158770205886688553">"Premjesti"</string> + <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Suzi"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">" POČETNI EKRAN "</annotation>" za kontrole"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni za način rada slika u slici."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomjeranje ulijevo"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomjeranje udesno"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomjeranje nagore"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomjeranje nadolje"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 8a522b3e6397..c8d0bcc1b2ef 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Configuració"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entra al mode de pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de pantalla en pantalla"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> està en pantalla en pantalla"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string> <string name="pip_play" msgid="3496151081459417097">"Reprodueix"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'aplicació no es pot obrir en pantalles secundàries."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalles"</string> + <string name="divider_title" msgid="5482989479865361192">"Separador de pantalla dividida"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla esquerra completa"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Pantalla esquerra al 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pantalla esquerra al 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toca per reiniciar aquesta aplicació i passar a pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca per reiniciar aquesta aplicació i obtenir una millor visualització."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tens problemes amb la càmera?\nToca per resoldre\'ls"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunes aplicacions funcionen millor en posició vertical"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prova una d\'aquestes opcions per treure el màxim profit de l\'espai"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gira el dispositiu per passar a pantalla completa"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Fes doble toc al costat d\'una aplicació per canviar-ne la posició"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Consulta i fes més coses"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arrossega una altra aplicació per utilitzar la pantalla dividida"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Fes doble toc fora d\'una aplicació per canviar-ne la posició"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entesos"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Desplega per obtenir més informació."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximitza"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimitza"</string> + <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml index 1c560c7afa06..94ba0db7e978 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantalla en pantalla"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sense títol)"</string> - <string name="pip_close" msgid="9135220303720555525">"Tanca PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Tanca"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string> - <string name="pip_move" msgid="1544227837964635439">"Mou pantalla en pantalla"</string> - <string name="pip_expand" msgid="7605396312689038178">"Desplega pantalla en pantalla"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Replega pantalla en pantalla"</string> + <string name="pip_move" msgid="158770205886688553">"Mou"</string> + <string name="pip_expand" msgid="1051966011679297308">"Desplega"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Replega"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Prem dos cops "<annotation icon="home_icon">" INICI "</annotation>" per accedir als controls"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla en pantalla."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mou cap a l\'esquerra"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mou cap a la dreta"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mou cap amunt"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mou cap avall"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Fet"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index d0cf80aef38c..7012294c0a88 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavení"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivovat rozdělenou obrazovku"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Nabídka"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Nabídka režimu obrazu v obraze"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Aplikace <xliff:g id="NAME">%s</xliff:g> je v režimu obraz v obraze"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Pokud nechcete, aby aplikace <xliff:g id="NAME">%s</xliff:g> tuto funkci používala, klepnutím otevřete nastavení a funkci vypněte."</string> <string name="pip_play" msgid="3496151081459417097">"Přehrát"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikace na sekundárním displeji nemusí fungovat."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikace nepodporuje spuštění na sekundárních displejích."</string> <string name="accessibility_divider" msgid="703810061635792791">"Čára rozdělující obrazovku"</string> + <string name="divider_title" msgid="5482989479865361192">"Čára rozdělující obrazovku"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Levá část na celou obrazovku"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % vlevo"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % vlevo"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string> + <string name="restart_button_description" msgid="6712141648865547958">"Klepnutím tuto aplikaci kvůli lepšímu zobrazení restartujete."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Některé aplikace fungují nejlépe na výšku"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Pokud chcete maximálně využít prostor, vyzkoušejte jednu z těchto možností"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Otočením zařízení přejděte do režimu celé obrazovky"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvojitým klepnutím vedle aplikace změňte její umístění"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lepší zobrazení a více možností"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Přetáhnutím druhé aplikace použijete rozdělenou obrazovku"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikaci změníte její umístění"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozbalením zobrazíte další informace."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovat"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovat"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml index 9a8cc2b4d70e..3ed85dce0433 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Obraz v obraze"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Bez názvu)"</string> - <string name="pip_close" msgid="9135220303720555525">"Ukončit obraz v obraze (PIP)"</string> + <string name="pip_close" msgid="2955969519031223530">"Zavřít"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Celá obrazovka"</string> - <string name="pip_move" msgid="1544227837964635439">"Přesunout PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Rozbalit PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Sbalit PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Přesunout"</string> + <string name="pip_expand" msgid="1051966011679297308">"Rozbalit"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Sbalit"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Ovládací prvky zobrazíte dvojitým stisknutím "<annotation icon="home_icon">"tlačítka plochy"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Nabídka režimu obrazu v obraze"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Přesunout doleva"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Přesunout doprava"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Přesunout nahoru"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Přesunout dolů"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Hotovo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index bb81c10c6e1b..e3c99ae5e2f8 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Indstillinger"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Åbn opdelt skærm"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu for integreret billede"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> vises som integreret billede"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Hvis du ikke ønsker, at <xliff:g id="NAME">%s</xliff:g> skal benytte denne funktion, kan du åbne indstillingerne og deaktivere den."</string> <string name="pip_play" msgid="3496151081459417097">"Afspil"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer muligvis ikke på sekundære skærme."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke åbnes på sekundære skærme."</string> <string name="accessibility_divider" msgid="703810061635792791">"Adskiller til opdelt skærm"</string> + <string name="divider_title" msgid="5482989479865361192">"Adskiller til opdelt skærm"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vis venstre del i fuld skærm"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Venstre 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Venstre 50 %"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tryk for at genstarte denne app, og gå til fuld skærm."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tryk for at genstarte denne app, så visningen forbedres."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du problemer med dit kamera?\nTryk for at gendanne det oprindelige format"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Nogle apps fungerer bedst i stående format"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prøv én af disse muligheder for at få mest muligt ud af dit rum"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Drej din enhed for at gå til fuld skærm"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tryk to gange ud for en app for at ændre dens placering"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se og gør mere"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Træk en anden app hertil for at bruge opdelt skærm"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryk to gange uden for en app for at justere dens placering"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Udvid for at få flere oplysninger."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimér"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string> + <string name="close_button_text" msgid="2913281996024033299">"Luk"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-da/strings_tv.xml b/libs/WindowManager/Shell/res/values-da/strings_tv.xml index cba660ac723c..09024428a825 100644 --- a/libs/WindowManager/Shell/res/values-da/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-da/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Integreret billede"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program uden titel)"</string> - <string name="pip_close" msgid="9135220303720555525">"Luk integreret billede"</string> + <string name="pip_close" msgid="2955969519031223530">"Luk"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Fuld skærm"</string> - <string name="pip_move" msgid="1544227837964635439">"Flyt PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Udvid PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Skjul PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Flyt"</string> + <string name="pip_expand" msgid="1051966011679297308">"Udvid"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Skjul"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Tryk to gange på "<annotation icon="home_icon">" HJEM "</annotation>" for at se indstillinger"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu for integreret billede."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Flyt til venstre"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Flyt til højre"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Flyt op"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Flyt ned"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Udfør"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index c5d945a982ef..d231b63109ce 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Einstellungen"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"„Geteilter Bildschirm“ 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> <string name="pip_notification_message" msgid="8854051911700302620">"Wenn du nicht möchtest, dass <xliff:g id="NAME">%s</xliff:g> diese Funktion verwendet, tippe, um die Einstellungen zu öffnen und die Funktion zu deaktivieren."</string> <string name="pip_play" msgid="3496151081459417097">"Wiedergeben"</string> @@ -36,6 +37,7 @@ <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> <string name="accessibility_divider" msgid="703810061635792791">"Bildschirmteiler"</string> + <string name="divider_title" msgid="5482989479865361192">"Bildschirmteiler"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vollbild links"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % links"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % links"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tippe, um die App im Vollbildmodus neu zu starten."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tippe, um diese App neu zu starten und die Ansicht zu verbessern."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Probleme mit der Kamera?\nZum Anpassen tippen."</string> <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="6688664582871779215">"Einige Apps funktionieren am besten im Hochformat"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Mithilfe dieser Möglichkeiten kannst du dein Display optimal nutzen"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gerät drehen, um zum Vollbildmodus zu wechseln"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Neben einer App doppeltippen, um die Position zu ändern"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Mehr sehen und erledigen"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Weitere App hineinziehen, um den Bildschirm zu teilen"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximieren"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimieren"</string> + <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-de/strings_tv.xml b/libs/WindowManager/Shell/res/values-de/strings_tv.xml index 02a1b66eb63f..18535c9d9338 100644 --- a/libs/WindowManager/Shell/res/values-de/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-de/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Bild im Bild"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Kein Sendungsname gefunden)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP schließen"</string> + <string name="pip_close" msgid="2955969519031223530">"Schließen"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Vollbild"</string> - <string name="pip_move" msgid="1544227837964635439">"BiB verschieben"</string> - <string name="pip_expand" msgid="7605396312689038178">"BiB maximieren"</string> - <string name="pip_collapse" msgid="5732233773786896094">"BiB minimieren"</string> + <string name="pip_move" msgid="158770205886688553">"Bewegen"</string> + <string name="pip_expand" msgid="1051966011679297308">"Maximieren"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Minimieren"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Für Steuerelemente zweimal "<annotation icon="home_icon">"STARTBILDSCHIRMTASTE"</annotation>" drücken"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menü „Bild im Bild“."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Nach links bewegen"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Nach rechts bewegen"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Nach oben bewegen"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Nach unten bewegen"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Fertig"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 70f55058925c..0a4f88a951c4 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Ρυθμίσεις"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Μετάβαση σε διαχωρισμό οθόνης"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Μενού"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Μενού λειτουργίας Picture-in-Picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Η λειτουργία picture-in-picture είναι ενεργή σε <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> @@ -36,6 +37,7 @@ <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="703810061635792791">"Διαχωριστικό οθόνης"</string> + <string name="divider_title" msgid="5482989479865361192">"Διαχωριστικό οθόνης"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Ορισμένες εφαρμογές λειτουργούν καλύτερα σε κατακόρυφο προσανατολισμό"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Δοκιμάστε μία από αυτές τις επιλογές για να αξιοποιήσετε στο έπακρο τον χώρο σας."</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Περιστρέψτε τη συσκευή σας για μετάβαση σε πλήρη οθόνη."</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Πατήστε δύο φορές δίπλα σε μια εφαρμογή για να αλλάξετε τη θέση της."</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Δείτε και κάντε περισσότερα"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Σύρετε σε μια άλλη εφαρμογή για διαχωρισμό οθόνης"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Μεγιστοποίηση"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Ελαχιστοποίηση"</string> + <string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-el/strings_tv.xml b/libs/WindowManager/Shell/res/values-el/strings_tv.xml index 24cd030cd754..5f8a004b0a1f 100644 --- a/libs/WindowManager/Shell/res/values-el/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-el/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-Picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Δεν υπάρχει τίτλος προγράμματος)"</string> - <string name="pip_close" msgid="9135220303720555525">"Κλείσιμο PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Κλείσιμο"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Πλήρης οθόνη"</string> - <string name="pip_move" msgid="1544227837964635439">"Μετακίνηση PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Ανάπτυξη PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Σύμπτυξη PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Μετακίνηση"</string> + <string name="pip_expand" msgid="1051966011679297308">"Ανάπτυξη"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Σύμπτυξη"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Πατήστε δύο φορές "<annotation icon="home_icon">" ΑΡΧΙΚΗ ΟΘΟΝΗ "</annotation>" για στοιχεία ελέγχου"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Μενού λειτουργίας Picture-in-Picture."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Μετακίνηση αριστερά"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Μετακίνηση δεξιά"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Μετακίνηση επάνω"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Μετακίνηση κάτω"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Τέλος"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 0b5aefa5c72e..acc75e46316d 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string> <string name="pip_play" msgid="3496151081459417097">"Play"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> + <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Drag in another app for split-screen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> + <string name="close_button_text" msgid="2913281996024033299">"Close"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml index 82257b42814d..839789b22a1c 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(No title program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Close"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string> - <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Move"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expand"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Collapse"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Picture-in-picture menu"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Move left"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Move right"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Move up"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Move down"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Done"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 0b5aefa5c72e..acc75e46316d 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string> <string name="pip_play" msgid="3496151081459417097">"Play"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> + <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Drag in another app for split-screen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> + <string name="close_button_text" msgid="2913281996024033299">"Close"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml index 82257b42814d..839789b22a1c 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(No title program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Close"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string> - <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Move"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expand"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Collapse"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Picture-in-picture menu"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Move left"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Move right"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Move up"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Move down"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Done"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 0b5aefa5c72e..acc75e46316d 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string> <string name="pip_play" msgid="3496151081459417097">"Play"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> + <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Drag in another app for split-screen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> + <string name="close_button_text" msgid="2913281996024033299">"Close"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml index 82257b42814d..839789b22a1c 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(No title program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Close"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string> - <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Move"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expand"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Collapse"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Picture-in-picture menu"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Move left"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Move right"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Move up"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Move down"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Done"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 0b5aefa5c72e..acc75e46316d 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string> <string name="pip_play" msgid="3496151081459417097">"Play"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split screen divider"</string> + <string name="divider_title" msgid="5482989479865361192">"Split screen divider"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Drag in another app for split-screen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> + <string name="close_button_text" msgid="2913281996024033299">"Close"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml index 82257b42814d..839789b22a1c 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(No title program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Close"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string> - <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Move"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expand"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Collapse"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Double-press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Picture-in-picture menu"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Move left"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Move right"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Move up"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Move down"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Done"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index 5c3d0f65374a..4e9f13fccf2c 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-Picture Menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string> <string name="pip_play" msgid="3496151081459417097">"Play"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="703810061635792791">"Split-screen divider"</string> + <string name="divider_title" msgid="5482989479865361192">"Split-screen divider"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Left full screen"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Left 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Drag in another app for split-screen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximize"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimize"</string> + <string name="close_button_text" msgid="2913281996024033299">"Close"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml index a6e494cfed3c..507e066e3812 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-Picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(No title program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Close"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string> - <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Move"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expand"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Collapse"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Double press "<annotation icon="home_icon">" HOME "</annotation>" for controls"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Picture-in-Picture menu."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Move left"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Move right"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Move up"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Move down"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Done"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index e523ae53b0cc..042bc8a5bd4d 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de pantalla en pantalla"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en modo de Pantalla en pantalla"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> use esta función, presiona para abrir la configuración y desactivarla."</string> <string name="pip_play" msgid="3496151081459417097">"Reproducir"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la app no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La app no puede iniciarse en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string> + <string name="divider_title" msgid="5482989479865361192">"Divisor de pantalla dividida"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla izquierda completa"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Izquierda: 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda: 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Presiona para reiniciar esta app y tener una mejor vista."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Tienes problemas con la cámara?\nPresiona para reajustarla"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se resolvió?\nPresiona para revertir los cambios"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No tienes problemas con la cámara? Presionar para descartar."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunas apps funcionan mejor en modo vertical"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prueba estas opciones para aprovechar al máximo tu espacio"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rota el dispositivo para ver la pantalla completa"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Presiona dos veces junto a una app para cambiar su posición"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Aprovecha más"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arrastra otra app para el modo de pantalla dividida"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Presiona dos veces fuera de una app para cambiar su ubicación"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expande para obtener más información."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> + <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml index 458f6b15b857..a2c27b79e04c 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantalla en pantalla"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Sin título de programa)"</string> - <string name="pip_close" msgid="9135220303720555525">"Cerrar PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Cerrar"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string> - <string name="pip_move" msgid="1544227837964635439">"Mover PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Maximizar PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Minimizar PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Mover"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expandir"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Contraer"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Presiona dos veces "<annotation icon="home_icon">"INICIO"</annotation>" para ver los controles"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla en pantalla"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover hacia la izquierda"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover hacia la derecha"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover hacia arriba"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover hacia abajo"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Listo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 974960708190..9234ad224f1b 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Ajustes"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de imagen en imagen"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en imagen en imagen"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca la notificación para abrir los ajustes y desactivarla."</string> <string name="pip_play" msgid="3496151081459417097">"Reproducir"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la aplicación no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La aplicación no se puede abrir en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Dividir la pantalla"</string> + <string name="divider_title" msgid="5482989479865361192">"Divisor de pantalla dividida"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla izquierda completa"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Izquierda 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda 50%"</string> @@ -46,10 +48,10 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior 30%"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string> - <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar Modo una mano"</string> + <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar modo Una mano"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o toca cualquier zona que haya encima de la aplicación"</string> - <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar Modo una mano"</string> - <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Salir del Modo una mano"</string> + <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo Una mano"</string> + <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Salir del modo Una mano"</string> <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Ajustes de las burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menú adicional"</string> <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Volver a añadir a la pila"</string> @@ -63,7 +65,7 @@ <string name="bubble_dismiss_text" msgid="8816558050659478158">"Cerrar burbuja"</string> <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostrar conversación en burbuja"</string> <string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatea con burbujas"</string> - <string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como iconos flotantes llamadas \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla."</string> + <string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como iconos flotantes llamados \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla."</string> <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Controla las burbujas"</string> <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string> <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y obtener una mejor vista."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunas aplicaciones funcionan mejor en vertical"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prueba una de estas opciones para sacar el máximo partido al espacio de tu pantalla"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gira el dispositivo para ir al modo de pantalla completa"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toca dos veces junto a una aplicación para cambiar su posición"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Consulta más información y haz más"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arrastra otra aplicación para activar la pantalla dividida"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dos veces fuera de una aplicación para cambiarla de posición"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mostrar más información"</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> + <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es/strings_tv.xml b/libs/WindowManager/Shell/res/values-es/strings_tv.xml index 0a690984dac5..75db421ec405 100644 --- a/libs/WindowManager/Shell/res/values-es/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-es/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Imagen en imagen"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sin título)"</string> - <string name="pip_close" msgid="9135220303720555525">"Cerrar PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Cerrar"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string> - <string name="pip_move" msgid="1544227837964635439">"Mover imagen en imagen"</string> - <string name="pip_expand" msgid="7605396312689038178">"Mostrar imagen en imagen"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Ocultar imagen en imagen"</string> + <string name="pip_move" msgid="158770205886688553">"Mover"</string> + <string name="pip_expand" msgid="1051966011679297308">"Mostrar"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Contraer"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Pulsa dos veces "<annotation icon="home_icon">"INICIO"</annotation>" para ver los controles"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de imagen en imagen."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover hacia la izquierda"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover hacia la derecha"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover hacia arriba"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover hacia abajo"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Hecho"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index a5f82a6452c4..ea5005d655b5 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Seaded"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Ava jagatud ekraanikuva"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menüü"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menüü Pilt pildis"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on režiimis Pilt pildis"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Kui te ei soovi, et rakendus <xliff:g id="NAME">%s</xliff:g> seda funktsiooni kasutaks, puudutage seadete avamiseks ja lülitage see välja."</string> <string name="pip_play" msgid="3496151081459417097">"Esita"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Rakendus ei pruugi teisesel ekraanil töötada."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekraanijagaja"</string> + <string name="divider_title" msgid="5482989479865361192">"Ekraanijagaja"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vasak täisekraan"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vasak: 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasak: 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Puudutage, et see rakendus parema vaate jaoks taaskäivitada."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kas teil on kaameraprobleeme?\nPuudutage ümberpaigutamiseks."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Mõni rakendus töötab kõige paremini vertikaalpaigutuses"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Proovige ühte neist valikutest, et oma ruumi parimal moel kasutada"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pöörake seadet, et aktiveerida täisekraanirežiim"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Topeltpuudutage rakenduse kõrval, et selle asendit muuta"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vaadake ja tehke rohkem"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Lohistage muusse rakendusse, et jagatud ekraanikuva kasutada"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Topeltpuudutage rakendusest väljaspool, et selle asendit muuta"</string> <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="maximize_button_text" msgid="1650859196290301963">"Maksimeeri"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimeeri"</string> + <string name="close_button_text" msgid="2913281996024033299">"Sule"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-et/strings_tv.xml b/libs/WindowManager/Shell/res/values-et/strings_tv.xml index dc0232303a70..e8fcb180c0c4 100644 --- a/libs/WindowManager/Shell/res/values-et/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-et/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pilt pildis"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programmi pealkiri puudub)"</string> - <string name="pip_close" msgid="9135220303720555525">"Sule PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Sule"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Täisekraan"</string> - <string name="pip_move" msgid="1544227837964635439">"Teisalda PIP-režiimi"</string> - <string name="pip_expand" msgid="7605396312689038178">"Laienda PIP-akent"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Ahenda PIP-aken"</string> + <string name="pip_move" msgid="158770205886688553">"Teisalda"</string> + <string name="pip_expand" msgid="1051966011679297308">"Laienda"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Ahenda"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Nuppude nägemiseks vajutage 2 korda nuppu "<annotation icon="home_icon">"AVAKUVA"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menüü Pilt pildis."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Teisalda vasakule"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Teisalda paremale"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Teisalda üles"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Teisalda alla"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Valmis"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index caa335a96222..1e5e48558493 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -22,8 +22,9 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Ezarpenak"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Sartu pantaila zatituan"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menua"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Pantaila txiki gainjarriaren menua"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Pantaila txiki gainjarrian dago <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="pip_notification_message" msgid="8854051911700302620">"Ez baduzu nahi <xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string> + <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea nahi ez baduzu, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string> <string name="pip_play" msgid="3496151081459417097">"Erreproduzitu"</string> <string name="pip_pause" msgid="690688849510295232">"Pausatu"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"Joan hurrengora"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pantaila-zatitzailea"</string> + <string name="divider_title" msgid="5482989479865361192">"Pantaila-zatitzailea"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ezarri ezkerraldea pantaila osoan"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ezarri ezkerraldea % 70en"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ezarri ezkerraldea % 50en"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Saka ezazu aplikazioa berrabiarazteko, eta ezarri pantaila osoko modua."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Hobeto ikusteko, sakatu hau aplikazioa berrabiarazteko."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Arazoak dauzkazu kamerarekin?\nBerriro doitzeko, sakatu hau."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ez al da konpondu?\nLeheneratzeko, sakatu hau."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Aplikazio batzuk orientazio bertikalean funtzionatzen dute hobekien"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Pantailako eremuari ahalik eta etekinik handiena ateratzeko, probatu aukera hauetakoren bat"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pantaila osoko modua erabiltzeko, biratu gailua"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Aplikazioaren posizioa aldatzeko, sakatu birritan haren ondoko edozein toki"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ikusi eta egin gauza gehiago"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Pantaila zatituta ikusteko, arrastatu beste aplikazio bat"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Aplikazioaren posizioa aldatzeko, sakatu birritan haren kanpoaldea"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ados"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Informazio gehiago lortzeko, zabaldu hau."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizatu"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizatu"</string> + <string name="close_button_text" msgid="2913281996024033299">"Itxi"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml index bce06da2c66f..07d75d2de9cd 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantaila txiki gainjarria"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa izengabea)"</string> - <string name="pip_close" msgid="9135220303720555525">"Itxi PIPa"</string> + <string name="pip_close" msgid="2955969519031223530">"Itxi"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pantaila osoa"</string> - <string name="pip_move" msgid="1544227837964635439">"Mugitu pantaila txiki gainjarria"</string> - <string name="pip_expand" msgid="7605396312689038178">"Zabaldu pantaila txiki gainjarria"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Tolestu pantaila txiki gainjarria"</string> + <string name="pip_move" msgid="158770205886688553">"Mugitu"</string> + <string name="pip_expand" msgid="1051966011679297308">"Zabaldu"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Tolestu"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Kontrolatzeko aukerak atzitzeko, sakatu birritan "<annotation icon="home_icon">" HASIERA "</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Pantaila txiki gainjarriaren menua."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Eraman ezkerrera"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Eraman eskuinera"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Eraman gora"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Eraman behera"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Eginda"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 761fb9ddeb2f..df43d55745a7 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"تنظیمات"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"ورود به حالت «صفحهٔ دونیمه»"</string> <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_play" msgid="3496151081459417097">"پخش"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"تقسیمکننده صفحه"</string> + <string name="divider_title" msgid="5482989479865361192">"تقسیمکننده صفحهٔ دونیمه"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"تمامصفحه چپ"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"٪۷۰ چپ"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"٪۵۰ چپ"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"برای بازراهاندازی این برنامه و تغییر به حالت تمامصفحه، ضربه بزنید."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"برخیاز برنامهها در حالت عمودی عملکرد بهتری دارند"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"با امتحان کردن یکی از این گزینهها، بیشترین بهره را از فضایتان ببرید"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"برای رفتن به حالت تمام صفحه، دستگاهتان را بچرخانید"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"در کنار برنامه دوضربه بزنید تا جابهجا شود"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"از چندین برنامه بهطور همزمان استفاده کنید"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"برای حالت صفحهٔ دونیمه، در برنامهای دیگر بکشید"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string> + <string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string> + <string name="close_button_text" msgid="2913281996024033299">"بستن"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fa/strings_tv.xml b/libs/WindowManager/Shell/res/values-fa/strings_tv.xml index ff9a03c6cefb..03f51d01a3a8 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"تصویر در تصویر"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(برنامه بدون عنوان)"</string> - <string name="pip_close" msgid="9135220303720555525">"بستن PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"بستن"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"تمام صفحه"</string> - <string name="pip_move" msgid="1544227837964635439">"انتقال PIP (تصویر در تصویر)"</string> - <string name="pip_expand" msgid="7605396312689038178">"گسترده کردن «تصویر در تصویر»"</string> - <string name="pip_collapse" msgid="5732233773786896094">"جمع کردن «تصویر در تصویر»"</string> + <string name="pip_move" msgid="158770205886688553">"انتقال"</string> + <string name="pip_expand" msgid="1051966011679297308">"گسترده کردن"</string> + <string name="pip_collapse" msgid="3903295106641385962">"جمع کردن"</string> <string name="pip_edu_text" msgid="3672999496647508701">" برای کنترلها، دکمه "<annotation icon="home_icon">"صفحه اصلی"</annotation>" را دوبار فشار دهید"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"منوی تصویر در تصویر."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"انتقال بهچپ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"انتقال بهراست"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"انتقال بهبالا"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"انتقال بهپایین"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"تمام"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index c809b4879e71..a4acec4b6701 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Asetukset"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Avaa jaettu näyttö"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Valikko"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Kuva kuvassa ‑valikko"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on kuva kuvassa ‑tilassa"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Jos et halua, että <xliff:g id="NAME">%s</xliff:g> voi käyttää tätä ominaisuutta, avaa asetukset napauttamalla ja poista se käytöstä."</string> <string name="pip_play" msgid="3496151081459417097">"Toista"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string> <string name="accessibility_divider" msgid="703810061635792791">"Näytön jakaja"</string> + <string name="divider_title" msgid="5482989479865361192">"Näytönjakaja"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vasen koko näytölle"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vasen 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasen 50 %"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Napauta, niin sovellus käynnistyy uudelleen paremmin näytölle sopivana."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Onko kameran kanssa ongelmia?\nKorjaa napauttamalla"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Osa sovelluksista toimii parhaiten pystytilassa"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Kokeile jotakin näistä vaihtoehdoista, jotta saat parhaan hyödyn näytön tilasta"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Käännä laitetta, niin se siirtyy koko näytön tilaan"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Kaksoisnapauta sovellusta, jos haluat siirtää sitä"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Näe ja tee enemmän"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Käytä jaettua näyttöä vetämällä tähän toinen sovellus"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kaksoisnapauta sovelluksen ulkopuolella, jos haluat siirtää sitä"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Katso lisätietoja laajentamalla."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Suurenna"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Pienennä"</string> + <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml index 3e8bf9032780..24ab7d99e180 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Kuva kuvassa"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Nimetön)"</string> - <string name="pip_close" msgid="9135220303720555525">"Sulje PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Sulje"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Koko näyttö"</string> - <string name="pip_move" msgid="1544227837964635439">"Siirrä PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Laajenna PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Tiivistä PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Siirrä"</string> + <string name="pip_expand" msgid="1051966011679297308">"Laajenna"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Tiivistä"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Asetukset: paina "<annotation icon="home_icon">"ALOITUSNÄYTTÖPAINIKETTA"</annotation>" kahdesti"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Kuva kuvassa ‑valikko."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Siirrä vasemmalle"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Siirrä oikealle"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Siirrä ylös"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Siirrä alas"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Valmis"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 62b2bb65a603..acc97f88358e 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entrer dans l\'écran partagé"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu d\'incrustation d\'image"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode d\'incrustation d\'image"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Si vous ne voulez pas que <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, touchez l\'écran pour ouvrir les paramètres, puis désactivez-la."</string> <string name="pip_play" msgid="3496151081459417097">"Lire"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string> + <string name="divider_title" msgid="5482989479865361192">"Séparateur d\'écran partagé"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Plein écran à la gauche"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % à la gauche"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % à la gauche"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Touchez pour redémarrer cette application et passer en plein écran."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Certaines applications fonctionnent mieux en mode portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Essayez l\'une de ces options pour tirer le meilleur parti de votre espace"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Faites pivoter votre appareil pour passer en plein écran"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Touchez deux fois à côté d\'une application pour la repositionner"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et en faire plus"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Faites glisser une autre application pour utiliser l\'écran partagé"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une application pour la repositionner"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string> + <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml index 66e13b89c64b..87651ec711d9 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Incrustation d\'image"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Aucun programme de titre)"</string> - <string name="pip_close" msgid="9135220303720555525">"Fermer mode IDI"</string> + <string name="pip_close" msgid="2955969519031223530">"Fermer"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Plein écran"</string> - <string name="pip_move" msgid="1544227837964635439">"Déplacer l\'image incrustée"</string> - <string name="pip_expand" msgid="7605396312689038178">"Développer l\'image incrustée"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Réduire l\'image incrustée"</string> + <string name="pip_move" msgid="158770205886688553">"Déplacer"</string> + <string name="pip_expand" msgid="1051966011679297308">"Développer"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Réduire"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Appuyez deux fois sur "<annotation icon="home_icon">" ACCUEIL "</annotation>" pour les commandes"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu d\'incrustation d\'image."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Déplacer vers la gauche"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Déplacer vers la droite"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Déplacer vers le haut"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Déplacer vers le bas"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index b3e22af0a3e3..d063f71347c7 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accéder à l\'écran partagé"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu \"Picture-in-picture\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode Picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Si vous ne voulez pas que l\'application <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, appuyez ici pour ouvrir les paramètres et la désactiver."</string> <string name="pip_play" msgid="3496151081459417097">"Lecture"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="703810061635792791">"Séparateur d\'écran partagé"</string> + <string name="divider_title" msgid="5482989479865361192">"Séparateur d\'écran partagé"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Écran de gauche en plein écran"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Écran de gauche à 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Écran de gauche à 50 %"</string> @@ -63,7 +65,7 @@ <string name="bubble_dismiss_text" msgid="8816558050659478158">"Fermer la bulle"</string> <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne pas afficher la conversation dans une bulle"</string> <string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatter en utilisant des bulles"</string> - <string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string> + <string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou de bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string> <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Contrôlez les bulles à tout moment"</string> <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Appuyez sur \"Gérer\" pour désactiver les bulles de cette application"</string> <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Appuyez pour redémarrer cette appli et avoir une meilleure vue."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Certaines applis fonctionnent mieux en mode Portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Essayez l\'une de ces options pour exploiter pleinement l\'espace"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Faites pivoter l\'appareil pour passer en plein écran"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Appuyez deux fois à côté d\'une appli pour la repositionner"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et interagir plus"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Appuyez deux fois en dehors d\'une appli pour la repositionner"</string> <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="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string> + <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml index ed9baf5b6215..37863fb82295 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programme sans titre)"</string> - <string name="pip_close" msgid="9135220303720555525">"Fermer mode PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Fermer"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Plein écran"</string> - <string name="pip_move" msgid="1544227837964635439">"Déplacer le PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Développer la fenêtre PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Réduire la fenêtre PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Déplacer"</string> + <string name="pip_expand" msgid="1051966011679297308">"Développer"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Réduire"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Menu de commandes : appuyez deux fois sur "<annotation icon="home_icon">"ACCUEIL"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu \"Picture-in-picture\"."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Déplacer vers la gauche"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Déplacer vers la droite"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Déplacer vers le haut"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Déplacer vers le bas"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"OK"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index b8e039602243..2cd8a4a060f2 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Inserir pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de pantalla superposta"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está na pantalla superposta"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Se non queres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca a configuración para abrir as opcións e desactivar a función."</string> <string name="pip_play" msgid="3496151081459417097">"Reproducir"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É posible que a aplicación non funcione nunha pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A aplicación non se pode iniciar en pantallas secundarias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de pantalla dividida"</string> + <string name="divider_title" msgid="5482989479865361192">"Divisor de pantalla dividida"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Pantalla completa á esquerda"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70 % á esquerda"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % á esquerda"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca o botón para reiniciar esta aplicación e gozar dunha mellor visualización."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tes problemas coa cámara?\nToca para reaxustala"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunhas aplicacións funcionan mellor en modo vertical"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Proba unha destas opcións para sacar o máximo proveito do espazo da pantalla"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Xira o dispositivo para ver o contido en pantalla completa"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toca dúas veces a carón dunha aplicación para cambiala de posición"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ver e facer máis"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arrastra outra aplicación para usar a pantalla dividida"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dúas veces fóra da aplicación para cambiala de posición"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Despregar para obter máis información."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> + <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml index a057434d7853..5d6de76c4deb 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantalla superposta"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sen título)"</string> - <string name="pip_close" msgid="9135220303720555525">"Pechar PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Pechar"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string> - <string name="pip_move" msgid="1544227837964635439">"Mover pantalla superposta"</string> - <string name="pip_expand" msgid="7605396312689038178">"Despregar pantalla superposta"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Contraer pantalla superposta"</string> + <string name="pip_move" msgid="158770205886688553">"Mover"</string> + <string name="pip_expand" msgid="1051966011679297308">"Despregar"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Contraer"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Preme "<annotation icon="home_icon">"INICIO"</annotation>" dúas veces para acceder aos controis"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla superposta."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover cara á esquerda"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover cara á dereita"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover cara arriba"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover cara abaixo"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Feito"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index deda2d755e20..2ade063ecd3c 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"સેટિંગ"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"વિભાજિત સ્ક્રીન મોડમાં દાખલ થાઓ"</string> <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_play" msgid="3496151081459417097">"ચલાવો"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string> + <string name="divider_title" msgid="5482989479865361192">"સ્ક્રીનને વિભાજિત કરતું વિભાજક"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"અમુક ઍપ પોર્ટ્રેટ મોડમાં શ્રેષ્ઠ રીતે કાર્ય કરે છે"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"તમારી સ્પેસનો વધુને વધુ લાભ લેવા માટે, આ વિકલ્પોમાંથી કોઈ એક અજમાવો"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"પૂર્ણ સ્ક્રીન મોડ લાગુ કરવા માટે, તમારા ડિવાઇસને ફેરવો"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"કોઈ ઍપની જગ્યા બદલવા માટે, તેની બાજુમાં બે વાર ટૅપ કરો"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"જુઓ અને બીજું ઘણું કરો"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"સ્ક્રીન વિભાજન માટે કોઈ અન્ય ઍપમાં ખેંચો"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"મોટું કરો"</string> + <string name="minimize_button_text" msgid="271592547935841753">"નાનું કરો"</string> + <string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gu/strings_tv.xml b/libs/WindowManager/Shell/res/values-gu/strings_tv.xml index d9525910e4c6..6c1b9db73582 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ચિત્રમાં-ચિત્ર"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(કોઈ ટાઇટલ પ્રોગ્રામ નથી)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP બંધ કરો"</string> + <string name="pip_close" msgid="2955969519031223530">"બંધ કરો"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"પૂર્ણ સ્ક્રીન"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP ખસેડો"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP મોટી કરો"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP નાની કરો"</string> + <string name="pip_move" msgid="158770205886688553">"ખસેડો"</string> + <string name="pip_expand" msgid="1051966011679297308">"મોટું કરો"</string> + <string name="pip_collapse" msgid="3903295106641385962">"નાનું કરો"</string> <string name="pip_edu_text" msgid="3672999496647508701">" નિયંત્રણો માટે "<annotation icon="home_icon">" હોમ "</annotation>" બટન પર બે વાર દબાવો"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ચિત્રમાં ચિત્ર મેનૂ."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ડાબે ખસેડો"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"જમણે ખસેડો"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ઉપર ખસેડો"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"નીચે ખસેડો"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"થઈ ગયું"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 36b11514c7e5..0fd83d3065aa 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन मोड में जाएं"</string> <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_play" msgid="3496151081459417097">"चलाएं"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"विभाजित स्क्रीन विभाजक"</string> + <string name="divider_title" msgid="5482989479865361192">"स्प्लिट स्क्रीन डिवाइडर"</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> @@ -65,20 +67,23 @@ <string name="bubbles_user_education_title" msgid="2112319053732691899">"बबल्स का इस्तेमाल करके चैट करें"</string> <string name="bubbles_user_education_description" msgid="4215862563054175407">"नई बातचीत फ़्लोटिंग आइकॉन या बबल्स की तरह दिखेंगी. बबल को खोलने के लिए टैप करें. इसे एक जगह से दूसरी जगह ले जाने के लिए खींचें और छोड़ें."</string> <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"जब चाहें, बबल्स को कंट्रोल करें"</string> - <string name="bubbles_user_education_manage" msgid="3460756219946517198">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'प्रबंधित करें\' पर टैप करें"</string> + <string name="bubbles_user_education_manage" msgid="3460756219946517198">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'मैनेज करें\' पर टैप करें"</string> <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ठीक है"</string> - <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के बबल्स मौजूद नहीं हैं"</string> + <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के कोई बबल्स नहीं हैं"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हाल ही के बबल्स और हटाए गए बबल्स यहां दिखेंगे"</string> <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="5887656107651190519">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन पर देखने के लिए टैप करें."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"कुछ ऐप्लिकेशन, पोर्ट्रेट मोड में सबसे अच्छी तरह काम करते हैं"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"जगह का पूरा इस्तेमाल करने के लिए, इनमें से किसी एक विकल्प को आज़माएं"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"फ़ुल स्क्रीन मोड में जाने के लिए, डिवाइस को घुमाएं"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बगल में दो बार टैप करें"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"पूरी जानकारी लेकर, बेहतर तरीके से काम करें"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"स्प्लिट स्क्रीन के लिए, दूसरे ऐप्लिकेशन को खींचें और छोड़ें"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"बड़ा करें"</string> + <string name="minimize_button_text" msgid="271592547935841753">"विंडो छोटी करें"</string> + <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml index d897ac73f80d..e0227253b2dc 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"पिक्चर में पिक्चर"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(कोई शीर्षक कार्यक्रम नहीं)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP बंद करें"</string> + <string name="pip_close" msgid="2955969519031223530">"बंद करें"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"फ़ुल स्क्रीन"</string> - <string name="pip_move" msgid="1544227837964635439">"पीआईपी को दूसरी जगह लेकर जाएं"</string> - <string name="pip_expand" msgid="7605396312689038178">"पीआईपी विंडो को बड़ा करें"</string> - <string name="pip_collapse" msgid="5732233773786896094">"पीआईपी विंडो को छोटा करें"</string> + <string name="pip_move" msgid="158770205886688553">"ले जाएं"</string> + <string name="pip_expand" msgid="1051966011679297308">"बड़ा करें"</string> + <string name="pip_collapse" msgid="3903295106641385962">"छोटा करें"</string> <string name="pip_edu_text" msgid="3672999496647508701">" कंट्रोल मेन्यू पर जाने के लिए, "<annotation icon="home_icon">" होम बटन"</annotation>" दो बार दबाएं"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"पिक्चर में पिक्चर मेन्यू."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"बाईं ओर ले जाएं"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"दाईं ओर ले जाएं"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ऊपर ले जाएं"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"नीचे ले जाएं"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"हो गया"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 5ecc5585a6e9..6ea911dc127c 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvorite podijeljeni zaslon"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Izbornik"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Izbornik slike u slici"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> jest na slici u slici"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ako ne želite da aplikacija <xliff:g id="NAME">%s</xliff:g> upotrebljava tu značajku, dodirnite da biste otvorili postavke i isključili je."</string> <string name="pip_play" msgid="3496151081459417097">"Reproduciraj"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdjelnik podijeljenog zaslona"</string> + <string name="divider_title" msgid="5482989479865361192">"Razdjelnik podijeljenog zaslona"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lijevi zaslon u cijeli zaslon"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Lijevi zaslon na 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevi zaslon na 50%"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Neke aplikacije najbolje funkcioniraju u portretnom usmjerenju"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Isprobajte jednu od ovih opcija da biste maksimalno iskoristili prostor"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zakrenite uređaj radi prikaza na cijelom zaslonu"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da biste joj promijenili položaj"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Gledajte i učinite više"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Povucite drugu aplikaciju unutra da biste podijelili zaslon"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste je premjestili"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Shvaćam"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite da biste saznali više."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziraj"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimiziraj"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml index 8f5f3164c4d7..a09e6e805f63 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika u slici"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez naslova)"</string> - <string name="pip_close" msgid="9135220303720555525">"Zatvori PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Zatvori"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Cijeli zaslon"</string> - <string name="pip_move" msgid="1544227837964635439">"Premjesti PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Proširi PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Sažmi PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Premjesti"</string> + <string name="pip_expand" msgid="1051966011679297308">"Proširi"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Sažmi"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Dvaput pritisnite "<annotation icon="home_icon">"POČETNI ZASLON"</annotation>" za kontrole"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Izbornik slike u slici."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pomaknite ulijevo"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pomaknite udesno"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pomaknite prema gore"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pomaknite prema dolje"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotovo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index 2295250e2853..e149f5c73e43 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Beállítások"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Váltás osztott képernyőre"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Kép a képben menü"</string> <string name="pip_notification_title" msgid="1347104727641353453">"A(z) <xliff:g id="NAME">%s</xliff:g> kép a képben funkciót használ"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ha nem szeretné, hogy a(z) <xliff:g id="NAME">%s</xliff:g> használja ezt a funkciót, koppintson a beállítások megnyitásához, és kapcsolja ki."</string> <string name="pip_play" msgid="3496151081459417097">"Lejátszás"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string> <string name="accessibility_divider" msgid="703810061635792791">"Elválasztó az osztott nézetben"</string> + <string name="divider_title" msgid="5482989479865361192">"Elválasztó az osztott nézetben"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Bal oldali teljes képernyőre"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Bal oldali 70%-ra"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Bal oldali 50%-ra"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string> + <string name="restart_button_description" msgid="6712141648865547958">"A jobb nézet érdekében koppintson az alkalmazás újraindításához."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerával kapcsolatos problémába ütközött?\nKoppintson a megoldáshoz."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Egyes alkalmazások álló tájolásban működnek a leghatékonyabban"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Próbálja ki az alábbi beállítások egyikét, hogy a legjobban ki tudja használni képernyő területét"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"A teljes képernyős mód elindításához forgassa el az eszközt"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Koppintson duplán az alkalmazás mellett az áthelyezéséhez"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Több mindent láthat és tehet"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Húzzon ide egy másik alkalmazást az osztott képernyő használatához"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Koppintson duplán az alkalmazáson kívül az áthelyezéséhez"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Értem"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kibontással további információkhoz juthat."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Teljes méret"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Kis méret"</string> + <string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hu/strings_tv.xml b/libs/WindowManager/Shell/res/values-hu/strings_tv.xml index fc8d79589121..5e065c2ad4e7 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Kép a képben"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Cím nélküli program)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP bezárása"</string> + <string name="pip_close" msgid="2955969519031223530">"Bezárás"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Teljes képernyő"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP áthelyezése"</string> - <string name="pip_expand" msgid="7605396312689038178">"Kép a képben kibontása"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Kép a képben összecsukása"</string> + <string name="pip_move" msgid="158770205886688553">"Áthelyezés"</string> + <string name="pip_expand" msgid="1051966011679297308">"Kibontás"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Összecsukás"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Vezérlők: "<annotation icon="home_icon">" KEZDŐKÉPERNYŐ "</annotation>" gomb kétszer megnyomva"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Kép a képben menü."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mozgatás balra"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mozgatás jobbra"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mozgatás felfelé"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mozgatás lefelé"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Kész"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 208936539094..070fb9470db5 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Կարգավորումներ"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Մտնել տրոհված էկրանի ռեժիմ"</string> <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_play" msgid="3496151081459417097">"Նվագարկել"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Տրոհված էկրանի բաժանիչ"</string> + <string name="divider_title" msgid="5482989479865361192">"Տրոհված էկրանի բաժանիչ"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Որոշ հավելվածներ լավագույնս աշխատում են դիմանկարի ռեժիմում"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Փորձեք այս տարբերակներից մեկը՝ տարածքը հնարավորինս արդյունավետ օգտագործելու համար"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Պտտեք սարքը՝ լիաէկրան ռեժիմին անցնելու համար"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Միաժամանակ կատարեք մի քանի առաջադրանք"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Քաշեք մյուս հավելվածի մեջ՝ էկրանի տրոհումն օգտագործելու համար"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Ծավալել"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Ծալել"</string> + <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml index f5665b8dd166..7963abf8972b 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Նկար նկարի մեջ"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Առանց վերնագրի ծրագիր)"</string> - <string name="pip_close" msgid="9135220303720555525">"Փակել PIP-ն"</string> + <string name="pip_close" msgid="2955969519031223530">"Փակել"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Լիէկրան"</string> - <string name="pip_move" msgid="1544227837964635439">"Տեղափոխել PIP-ը"</string> - <string name="pip_expand" msgid="7605396312689038178">"Ծավալել PIP-ը"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Ծալել PIP-ը"</string> + <string name="pip_move" msgid="158770205886688553">"Տեղափոխել"</string> + <string name="pip_expand" msgid="1051966011679297308">"Ծավալել"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Ծալել"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Կարգավորումների համար կրկնակի սեղմեք "<annotation icon="home_icon">"ԳԼԽԱՎՈՐ ԷԿՐԱՆ"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"«Նկար նկարի մեջ» ռեժիմի ընտրացանկ։"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Տեղափոխել ձախ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Տեղափոխել աջ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Տեղափոխել վերև"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Տեղափոխել ներքև"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Պատրաստ է"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 1b46b2fe2570..b5a1de166e82 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Setelan"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk ke mode layar terpisah"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu Picture-in-Picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> adalah picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, ketuk untuk membuka setelan dan menonaktifkannya."</string> <string name="pip_play" msgid="3496151081459417097">"Putar"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pembagi layar terpisah"</string> + <string name="divider_title" msgid="5482989479865361192">"Pembagi layar terpisah"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Layar penuh di kiri"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kiri 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ketuk untuk memulai ulang aplikasi ini agar mendapatkan tampilan yang lebih baik."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Masalah kamera?\nKetuk untuk memperbaiki"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Beberapa aplikasi berfungsi paling baik dalam mode potret"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Coba salah satu opsi berikut untuk mengoptimalkan area layar Anda"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Putar perangkat untuk tampilan layar penuh"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ketuk dua kali di samping aplikasi untuk mengubah posisinya"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lihat dan lakukan lebih banyak hal"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Tarik aplikasi lain untuk menggunakan layar terpisah"</string> + <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="maximize_button_text" msgid="1650859196290301963">"Maksimalkan"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimalkan"</string> + <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-in/strings_tv.xml b/libs/WindowManager/Shell/res/values-in/strings_tv.xml index a1535653f679..7d37154bb86c 100644 --- a/libs/WindowManager/Shell/res/values-in/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-in/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-Picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program tanpa judul)"</string> - <string name="pip_close" msgid="9135220303720555525">"Tutup PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Tutup"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Layar penuh"</string> - <string name="pip_move" msgid="1544227837964635439">"Pindahkan PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Luaskan PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Ciutkan PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Pindahkan"</string> + <string name="pip_expand" msgid="1051966011679297308">"Luaskan"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Ciutkan"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Tekan dua kali "<annotation icon="home_icon">" HOME "</annotation>" untuk membuka kontrol"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu Picture-in-Picture."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pindahkan ke kiri"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pindahkan ke kanan"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pindahkan ke atas"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pindahkan ke bawah"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Selesai"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index a201c95137f3..4e935a2bc5cd 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Stillingar"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Opna skjáskiptingu"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Valmynd"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Valmynd fyrir mynd í mynd"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er með mynd í mynd"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ef þú vilt ekki að <xliff:g id="NAME">%s</xliff:g> noti þennan eiginleika skaltu ýta til að opna stillingarnar og slökkva á því."</string> <string name="pip_play" msgid="3496151081459417097">"Spila"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Forrit styður ekki opnun á öðrum skjá."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skjáskipting"</string> + <string name="divider_title" msgid="5482989479865361192">"Skjáskipting"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Vinstri á öllum skjánum"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vinstri 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vinstri 50%"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ýta 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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sum forrit virka best í skammsniði"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prófaðu einhvern af eftirfarandi valkostum til að nýta plássið sem best"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Snúðu tækinu til að nota allan skjáinn"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ýttu tvisvar við hlið forritsins til að færa það"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Sjáðu og gerðu meira"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Dragðu annað forrit inn til að nota skjáskiptingu"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ýttu tvisvar utan við forrit til að færa það"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ég skil"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Stækka til að sjá frekari upplýsingar."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Stækka"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minnka"</string> + <string name="close_button_text" msgid="2913281996024033299">"Loka"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-is/strings_tv.xml b/libs/WindowManager/Shell/res/values-is/strings_tv.xml index 70ca1afe3aea..1490cb98e034 100644 --- a/libs/WindowManager/Shell/res/values-is/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-is/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Mynd í mynd"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Efni án titils)"</string> - <string name="pip_close" msgid="9135220303720555525">"Loka mynd í mynd"</string> + <string name="pip_close" msgid="2955969519031223530">"Loka"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Allur skjárinn"</string> - <string name="pip_move" msgid="1544227837964635439">"Færa innfellda mynd"</string> - <string name="pip_expand" msgid="7605396312689038178">"Stækka innfellda mynd"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Minnka innfellda mynd"</string> + <string name="pip_move" msgid="158770205886688553">"Færa"</string> + <string name="pip_expand" msgid="1051966011679297308">"Stækka"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Minnka"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Ýttu tvisvar á "<annotation icon="home_icon">" HEIM "</annotation>" til að opna stillingar"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Valmynd fyrir mynd í mynd."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Færa til vinstri"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Færa til hægri"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Færa upp"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Færa niður"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Lokið"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 7157ed088d30..c4b572185618 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Impostazioni"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accedi a schermo diviso"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu Picture in picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> è in Picture in picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Se non desideri che l\'app <xliff:g id="NAME">%s</xliff:g> utilizzi questa funzione, tocca per aprire le impostazioni e disattivarla."</string> <string name="pip_play" msgid="3496151081459417097">"Riproduci"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"L\'app potrebbe non funzionare su un display secondario."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'app non supporta l\'avvio su display secondari."</string> <string name="accessibility_divider" msgid="703810061635792791">"Strumento per schermo diviso"</string> + <string name="divider_title" msgid="5482989479865361192">"Strumento per schermo diviso"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Schermata sinistra a schermo intero"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Schermata sinistra al 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Schermata sinistra al 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tocca per riavviare l\'app e passare alla modalità a schermo intero."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tocca per riavviare quest\'app per una migliore visualizzazione."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi con la fotocamera?\nTocca per risolverli"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Alcune app funzionano in modo ottimale in verticale"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prova una di queste opzioni per ottimizzare lo spazio a tua disposizione"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ruota il dispositivo per passare alla modalità a schermo intero"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tocca due volte accanto a un\'app per riposizionarla"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Visualizza più contenuti e fai di più"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Trascina in un\'altra app per usare lo schermo diviso"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tocca due volte fuori da un\'app per riposizionarla"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Espandi per avere ulteriori informazioni."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Ingrandisci"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Riduci a icona"</string> + <string name="close_button_text" msgid="2913281996024033299">"Chiudi"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-it/strings_tv.xml b/libs/WindowManager/Shell/res/values-it/strings_tv.xml index cda627517872..a48516f2588e 100644 --- a/libs/WindowManager/Shell/res/values-it/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-it/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture in picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programma senza titolo)"</string> - <string name="pip_close" msgid="9135220303720555525">"Chiudi PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Chiudi"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Schermo intero"</string> - <string name="pip_move" msgid="1544227837964635439">"Sposta PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Espandi PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Comprimi PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Sposta"</string> + <string name="pip_expand" msgid="1051966011679297308">"Espandi"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Comprimi"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Premi due volte "<annotation icon="home_icon">" HOME "</annotation>" per aprire i controlli"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu Picture in picture."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Sposta a sinistra"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Sposta a destra"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Sposta su"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Sposta giù"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Fine"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 52a6b0676222..edd2cb6411de 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"הגדרות"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"כניסה למסך המפוצל"</string> <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_play" msgid="3496151081459417097">"הפעלה"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"מחלק מסך מפוצל"</string> + <string name="divider_title" msgid="5482989479865361192">"מחלק מסך מפוצל"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"חלק מהאפליקציות פועלות בצורה הטובה ביותר במצב תצוגה לאורך"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"כדי להפיק את המרב משטח המסך, ניתן לנסות את אחת מהאפשרויות האלה"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"מסובבים את המכשיר כדי לעבור לתצוגה במסך מלא"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"מקישים הקשה כפולה ליד אפליקציה כדי למקם אותה מחדש"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"רוצה לראות ולעשות יותר?"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"צריך לגרור אפליקציה אחרת כדי להשתמש במסך מפוצל"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string> + <string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string> + <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml index 30ce97b998ca..2af1896d3c67 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"תמונה בתוך תמונה"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(תוכנית ללא כותרת)"</string> - <string name="pip_close" msgid="9135220303720555525">"סגירת PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"סגירה"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"מסך מלא"</string> - <string name="pip_move" msgid="1544227837964635439">"העברת תמונה בתוך תמונה (PIP)"</string> - <string name="pip_expand" msgid="7605396312689038178">"הרחבת חלון תמונה-בתוך-תמונה"</string> - <string name="pip_collapse" msgid="5732233773786896094">"כיווץ של חלון תמונה-בתוך-תמונה"</string> + <string name="pip_move" msgid="158770205886688553">"העברה"</string> + <string name="pip_expand" msgid="1051966011679297308">"הרחבה"</string> + <string name="pip_collapse" msgid="3903295106641385962">"כיווץ"</string> <string name="pip_edu_text" msgid="3672999496647508701">" לחיצה כפולה על "<annotation icon="home_icon">" הלחצן הראשי "</annotation>" תציג את אמצעי הבקרה"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"תפריט \'תמונה בתוך תמונה\'."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"הזזה שמאלה"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"הזזה ימינה"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"הזזה למעלה"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"הזזה למטה"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"סיום"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 5a25c24ba034..721ef6c66a86 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"分割画面に切り替え"</string> <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>でこの機能を使用しない場合は、タップして設定を開いて OFF にしてください。"</string> <string name="pip_play" msgid="3496151081459417097">"再生"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"分割画面の分割線"</string> + <string name="divider_title" msgid="5482989479865361192">"分割画面の分割線"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"タップしてこのアプリを再起動すると、全画面表示になります。"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"アプリによっては縦向きにすると正常に動作します"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"スペースを最大限に活用するには、以下の方法のいずれかをお試しください"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"全画面表示にするにはデバイスを回転させてください"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"位置を変えるにはアプリの横をダブルタップしてください"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"表示を拡大して機能を強化"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"分割画面にするにはもう 1 つのアプリをドラッグしてください"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"位置を変えるにはアプリの外側をダブルタップしてください"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"開くと詳細が表示されます。"</string> + <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> + <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> + <string name="close_button_text" msgid="2913281996024033299">"閉じる"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ja/strings_tv.xml b/libs/WindowManager/Shell/res/values-ja/strings_tv.xml index e58e7bf6fabc..bc7dcb7aa029 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ピクチャー イン ピクチャー"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(無題の番組)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP を閉じる"</string> + <string name="pip_close" msgid="2955969519031223530">"閉じる"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"全画面表示"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP を移動"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP を開く"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP を閉じる"</string> + <string name="pip_move" msgid="158770205886688553">"移動"</string> + <string name="pip_expand" msgid="1051966011679297308">"開く"</string> + <string name="pip_collapse" msgid="3903295106641385962">"閉じる"</string> <string name="pip_edu_text" msgid="3672999496647508701">" コントロールにアクセス: "<annotation icon="home_icon">" ホーム "</annotation>" を 2 回押します"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ピクチャー イン ピクチャーのメニューです。"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"左に移動"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"右に移動"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"上に移動"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"下に移動"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"完了"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index bff86fa6ffe2..d4aaba0ca05a 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"პარამეტრები"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"გაყოფილ ეკრანში შესვლა"</string> <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_play" msgid="3496151081459417097">"დაკვრა"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string> + <string name="divider_title" msgid="5482989479865361192">"ეკრანის გაყოფის გამყოფი"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ზოგიერთი აპი უკეთ მუშაობს პორტრეტის რეჟიმში"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"გამოცადეთ ამ ვარიანტებიდან ერთ-ერთი, რათა მაქსიმალურად ისარგებლოთ თქვენი მეხსიერებით"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"მოატრიალეთ თქვენი მოწყობილობა სრული ეკრანის გასაშლელად"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ორმაგად შეეხეთ აპის გვერდითა სივრცეს, რათა ის სხვაგან გადაიტანოთ"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"მეტის ნახვა და გაკეთება"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ეკრანის გასაყოფად ჩავლებით გადაიტანეთ სხვა აპში"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"მაქსიმალურად გაშლა"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ჩაკეცვა"</string> + <string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ka/strings_tv.xml b/libs/WindowManager/Shell/res/values-ka/strings_tv.xml index b09686646c8b..898dac2aca88 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ეკრანი ეკრანში"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(პროგრამის სათაურის გარეშე)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP-ის დახურვა"</string> + <string name="pip_close" msgid="2955969519031223530">"დახურვა"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"სრულ ეკრანზე"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP გადატანა"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP-ის გაშლა"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP-ის ჩაკეცვა"</string> + <string name="pip_move" msgid="158770205886688553">"გადაადგილება"</string> + <string name="pip_expand" msgid="1051966011679297308">"გაშლა"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ჩაკეცვა"</string> <string name="pip_edu_text" msgid="3672999496647508701">" მართვის საშუალებებზე წვდომისთვის ორმაგად დააჭირეთ "<annotation icon="home_icon">" მთავარ ღილაკს "</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"მენიუ „ეკრანი ეკრანში“."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"მარცხნივ გადატანა"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"მარჯვნივ გადატანა"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ზემოთ გადატანა"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ქვემოთ გადატანა"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"მზადაა"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index f57f3f581c85..a4ff2a93f00b 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Параметрлер"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Бөлінген экранға кіру"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Mәзір"</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_play" msgid="3496151081459417097">"Ойнату"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Бөлінген экран бөлгіші"</string> + <string name="divider_title" msgid="5482989479865361192">"Бөлінген экран бөлгіші"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Кейбір қолданба портреттік режимде жақсы жұмыс істейді"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Экранды тиімді пайдалану үшін мына опциялардың бірін байқап көріңіз."</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Толық экранға ауысу үшін құрылғыңызды бұрыңыз."</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Қолданбаның орнын ауыстыру үшін жанынан екі рет түртіңіз."</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Қосымша ақпаратты қарап, әрекеттер жасау"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Экранды бөлу үшін басқа қолданбаға сүйреңіз."</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Жаю"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Кішірейту"</string> + <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kk/strings_tv.xml b/libs/WindowManager/Shell/res/values-kk/strings_tv.xml index 7bade0dff0d9..cdf564fb4ca0 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Суреттегі сурет"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Атаусыз бағдарлама)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP жабу"</string> + <string name="pip_close" msgid="2955969519031223530">"Жабу"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Толық экран"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP клипін жылжыту"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP терезесін жаю"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP терезесін жию"</string> + <string name="pip_move" msgid="158770205886688553">"Жылжыту"</string> + <string name="pip_expand" msgid="1051966011679297308">"Жаю"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Жию"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Басқару элементтері: "<annotation icon="home_icon">" НЕГІЗГІ ЭКРАН "</annotation>" түймесін екі рет басыңыз."</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"\"Сурет ішіндегі сурет\" мәзірі."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Солға жылжыту"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Оңға жылжыту"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Жоғары жылжыту"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Төмен жылжыту"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Дайын"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 5c04f881fe0e..47367f5ea526 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ការកំណត់"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"ចូលមុខងារបំបែកអេក្រង់"</string> <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_play" msgid="3496151081459417097">"លេង"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"កម្មវិធីចែកអេក្រង់បំបែក"</string> + <string name="divider_title" msgid="5482989479865361192">"បន្ទាត់ខណ្ឌចែកអេក្រង់បំបែក"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ចុចដើម្បីចាប់ផ្ដើមកម្មវិធីនេះឡើងវិញ រួចចូលប្រើពេញអេក្រង់។"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"កម្មវិធីមួយចំនួនដំណើរការបានប្រសើរបំផុតក្នុងទិសដៅបញ្ឈរ"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"សាកល្បងជម្រើសមួយក្នុងចំណោមទាំងនេះ ដើម្បីទទួលបានអត្ថប្រយោជន៍ច្រើនបំផុតពីកន្លែងទំនេររបស់អ្នក"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"បង្វិលឧបករណ៍របស់អ្នក ដើម្បីចូលប្រើអេក្រង់ពេញ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ចុចពីរដងនៅជាប់កម្មវិធីណាមួយ ដើម្បីប្ដូរទីតាំងកម្មវិធីនោះ"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"មើលឃើញ និងធ្វើបានកាន់តែច្រើន"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"អូសកម្មវិធីមួយទៀតចូល ដើម្បីប្រើមុខងារបំបែកអេក្រង់"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ពង្រីក"</string> + <string name="minimize_button_text" msgid="271592547935841753">"បង្រួម"</string> + <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-km/strings_tv.xml b/libs/WindowManager/Shell/res/values-km/strings_tv.xml index 721be1fc1650..1a7ae813c1d3 100644 --- a/libs/WindowManager/Shell/res/values-km/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-km/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"រូបក្នុងរូប"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(កម្មវិធីគ្មានចំណងជើង)"</string> - <string name="pip_close" msgid="9135220303720555525">"បិទ PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"បិទ"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ពេញអេក្រង់"</string> - <string name="pip_move" msgid="1544227837964635439">"ផ្លាស់ទី PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"ពង្រីក PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"បង្រួម PIP"</string> + <string name="pip_move" msgid="158770205886688553">"ផ្លាស់ទី"</string> + <string name="pip_expand" msgid="1051966011679297308">"ពង្រីក"</string> + <string name="pip_collapse" msgid="3903295106641385962">"បង្រួម"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ចុចពីរដងលើ"<annotation icon="home_icon">"ប៊ូតុងដើម"</annotation>" ដើម្បីបើកផ្ទាំងគ្រប់គ្រង"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ម៉ឺនុយរូបក្នុងរូប"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ផ្លាស់ទីទៅឆ្វេង"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ផ្លាស់ទីទៅស្តាំ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ផ្លាស់ទីឡើងលើ"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ផ្លាស់ទីចុះក្រោម"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"រួចរាល់"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index e91383caa009..001e12298cdf 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"ಸ್ಪ್ಲಿಟ್-ಸ್ಕ್ರೀನ್ಗೆ ಪ್ರವೇಶಿಸಿ"</string> <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_play" msgid="3496151081459417097">"ಪ್ಲೇ"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string> + <string name="divider_title" msgid="5482989479865361192">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ಕೆಲವು ಆ್ಯಪ್ಗಳು ಪೋರ್ಟ್ರೇಟ್ ಮೋಡ್ನಲ್ಲಿ ಅತ್ಯುತ್ತಮವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ನಿಮ್ಮ ಸ್ಥಳಾವಕಾಶದ ಅತಿಹೆಚ್ಚು ಪ್ರಯೋಜನ ಪಡೆಯಲು ಈ ಆಯ್ಕೆಗಳಲ್ಲಿ ಒಂದನ್ನು ಬಳಸಿ ನೋಡಿ"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ಗೆ ಹೋಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ಆ್ಯಪ್ ಒಂದರ ಸ್ಥಾನವನ್ನು ಬದಲಾಯಿಸಲು ಅದರ ಪಕ್ಕದಲ್ಲಿ ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ನೋಡಿ ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ಗಾಗಿ ಮತ್ತೊಂದು ಆ್ಯಪ್ನಲ್ಲಿ ಎಳೆಯಿರಿ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ಹಿಗ್ಗಿಸಿ"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ಕುಗ್ಗಿಸಿ"</string> + <string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml index 8310c8a1169c..45de068c80a0 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ಶೀರ್ಷಿಕೆ ರಹಿತ ಕಾರ್ಯಕ್ರಮ)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP ಮುಚ್ಚಿ"</string> + <string name="pip_close" msgid="2955969519031223530">"ಮುಚ್ಚಿರಿ"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ಪೂರ್ಣ ಪರದೆ"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP ಅನ್ನು ಸರಿಸಿ"</string> - <string name="pip_expand" msgid="7605396312689038178">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ವಿಸ್ತರಿಸಿ"</string> - <string name="pip_collapse" msgid="5732233773786896094">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ಕುಗ್ಗಿಸಿ"</string> + <string name="pip_move" msgid="158770205886688553">"ಸರಿಸಿ"</string> + <string name="pip_expand" msgid="1051966011679297308">"ವಿಸ್ತೃತಗೊಳಿಸಿ"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ಕುಗ್ಗಿಸಿ"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ಕಂಟ್ರೋಲ್ಗಳಿಗಾಗಿ "<annotation icon="home_icon">" ಹೋಮ್ "</annotation>" ಅನ್ನು ಎರಡು ಬಾರಿ ಒತ್ತಿ"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ ಮೆನು."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ಮೇಲಕ್ಕೆ ಸರಿಸಿ"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ಕೆಳಗೆ ಸರಿಸಿ"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ಮುಗಿದಿದೆ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 104ba3f22c96..27e294ebd5d6 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"설정"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"화면 분할 모드로 전환"</string> <string name="pip_menu_title" msgid="5393619322111827096">"메뉴"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"PIP 모드 메뉴"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>에서 PIP 사용 중"</string> <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g>에서 이 기능이 사용되는 것을 원하지 않는 경우 탭하여 설정을 열고 기능을 사용 중지하세요."</string> <string name="pip_play" msgid="3496151081459417097">"재생"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"화면 분할기"</string> + <string name="divider_title" msgid="5482989479865361192">"화면 분할기"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"일부 앱은 세로 모드에서 가장 잘 작동함"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"공간을 최대한 이용할 수 있도록 이 옵션 중 하나를 시도해 보세요."</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"전체 화면 모드로 전환하려면 기기를 회전하세요."</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"앱 위치를 조정하려면 앱 옆을 두 번 탭하세요."</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"더 많은 정보를 보고 더 많은 작업을 처리하세요"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"화면 분할을 사용하려면 다른 앱을 드래그해 가져옵니다."</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> + <string name="maximize_button_text" msgid="1650859196290301963">"최대화"</string> + <string name="minimize_button_text" msgid="271592547935841753">"최소화"</string> + <string name="close_button_text" msgid="2913281996024033299">"닫기"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml index a3e055a515a1..9e8f1f1258a5 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"PIP 모드"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(제목 없는 프로그램)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP 닫기"</string> + <string name="pip_close" msgid="2955969519031223530">"닫기"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"전체화면"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP 이동"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP 펼치기"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP 접기"</string> + <string name="pip_move" msgid="158770205886688553">"이동"</string> + <string name="pip_expand" msgid="1051966011679297308">"펼치기"</string> + <string name="pip_collapse" msgid="3903295106641385962">"접기"</string> <string name="pip_edu_text" msgid="3672999496647508701">" 제어 메뉴에 액세스하려면 "<annotation icon="home_icon">" 홈 "</annotation>"을 두 번 누르세요."</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"PIP 모드 메뉴입니다."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"왼쪽으로 이동"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"오른쪽으로 이동"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"위로 이동"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"아래로 이동"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"완료"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 8203622a33fc..d46fb66cff54 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Жөндөөлөр"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Экранды бөлүү режимине өтүү"</string> <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_play" msgid="3496151081459417097">"Ойнотуу"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Экранды бөлгүч"</string> + <string name="divider_title" msgid="5482989479865361192">"Экранды бөлгүч"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн таптап коюңуз."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Айрым колдонмолорду тигинен иштетүү туура болот"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Иш чөйрөсүнүн бардык мүмкүнчүлүктөрүн пайдалануу үчүн бул параметрлердин бирин колдонуп көрүңүз"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Толук экран режимине өтүү үчүн түзмөктү буруңуз"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Колдонмонун ракурсун өзгөртүү үчүн анын тушуна эки жолу басыңыз"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Көрүп, көбүрөөк нерселерди жасаңыз"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Экранды бөлүү үчүн башка колдонмону сүйрөңүз"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Чоңойтуу"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Кичирейтүү"</string> + <string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml index 887ac52c8e43..19fac5876bb0 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Сүрөттөгү сүрөт"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Аталышы жок программа)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP\'ти жабуу"</string> + <string name="pip_close" msgid="2955969519031223530">"Жабуу"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Толук экран"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP\'ти жылдыруу"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP\'ти жайып көрсөтүү"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP\'ти жыйыштыруу"</string> + <string name="pip_move" msgid="158770205886688553">"Жылдыруу"</string> + <string name="pip_expand" msgid="1051966011679297308">"Жайып көрсөтүү"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Жыйыштыруу"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Башкаруу элементтерин ачуу үчүн "<annotation icon="home_icon">" БАШКЫ БЕТ "</annotation>" баскычын эки жолу басыңыз"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Сүрөт ичиндеги сүрөт менюсу."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Солго жылдыруу"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Оңго жылдыруу"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Жогору жылдыруу"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Төмөн жылдыруу"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Бүттү"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index 24396786f9d8..d7d34d703431 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ການຕັ້ງຄ່າ"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"ເຂົ້າການແບ່ງໜ້າຈໍ"</string> <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_play" msgid="3496151081459417097">"ຫຼິ້ນ"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string> + <string name="divider_title" msgid="5482989479865361192">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</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> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string> - <string name="restart_button_description" msgid="5887656107651190519">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ແອັບບາງຢ່າງເຮັດວຽກໄດ້ດີທີ່ສຸດໃນໂໝດລວງຕັ້ງ"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ໃຫ້ລອງຕົວເລືອກໃດໜຶ່ງເຫຼົ່ານີ້ເພື່ອໃຊ້ປະໂຫຍດຈາກພື້ນທີ່ຂອງທ່ານໃຫ້ໄດ້ສູງສຸດ"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ໝຸນອຸປະກອນຂອງທ່ານເພື່ອໃຊ້ແບບເຕັມຈໍ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ແຕະສອງເທື່ອໃສ່ຖັດຈາກແອັບໃດໜຶ່ງເພື່ອຈັດຕຳແໜ່ງຂອງມັນຄືນໃໝ່"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ເບິ່ງ ແລະ ເຮັດຫຼາຍຂຶ້ນ"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ລາກແອັບອື່ນເຂົ້າມາເພື່ອແບ່ງໜ້າຈໍ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ຫຍໍ້ລົງ"</string> + <string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml index 91c4a033356d..6cd0f37c516c 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ການສະແດງຜົນຊ້ອນກັນ"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ໂປຣແກຣມບໍ່ມີຊື່)"</string> - <string name="pip_close" msgid="9135220303720555525">"ປິດ PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"ປິດ"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ເຕັມໜ້າຈໍ"</string> - <string name="pip_move" msgid="1544227837964635439">"ຍ້າຍ PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"ຂະຫຍາຍ PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"ຫຍໍ້ PIP ລົງ"</string> + <string name="pip_move" msgid="158770205886688553">"ຍ້າຍ"</string> + <string name="pip_expand" msgid="1051966011679297308">"ຂະຫຍາຍ"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ຫຍໍ້"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ກົດ "<annotation icon="home_icon">" HOME "</annotation>" ສອງເທື່ອສຳລັບການຄວບຄຸມ"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ເມນູການສະແດງຜົນຊ້ອນກັນ."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ຍ້າຍໄປຊ້າຍ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ຍ້າຍໄປຂວາ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ຍ້າຍຂຶ້ນ"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ຍ້າຍລົງ"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ແລ້ວໆ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index e2ae643ad308..4b16f63666d0 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Nustatymai"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Įjungti išskaidyto ekrano režimą"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Vaizdo vaizde meniu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> rodom. vaizdo vaizde"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Jei nenorite, kad „<xliff:g id="NAME">%s</xliff:g>“ naudotų šią funkciją, palietę atidarykite nustatymus ir išjunkite ją."</string> <string name="pip_play" msgid="3496151081459417097">"Leisti"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Programa gali neveikti antriniame ekrane."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programa nepalaiko paleisties antriniuose ekranuose."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skaidyto ekrano daliklis"</string> + <string name="divider_title" msgid="5482989479865361192">"Skaidyto ekrano daliklis"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Kairysis ekranas viso ekrano režimu"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kairysis ekranas 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kairysis ekranas 50 %"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Palieskite, kad paleistumėte iš naujo šią programą ir įjungtumėte viso ekrano režimą."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Palieskite, kad iš naujo paleistumėte šią programą ir matytumėte aiškiau."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Iškilo problemų dėl kameros?\nPalieskite, kad pritaikytumėte iš naujo"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Kai kurios programos geriausiai veikia stačiuoju režimu"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Pabandykite naudoti vieną iš šių parinkčių, kad išnaudotumėte visą vietą"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pasukite įrenginį, kad įjungtumėte viso ekrano režimą"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dukart palieskite šalia programos, kad pakeistumėte jos poziciją"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Daugiau turinio ir funkcijų"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Vilkite kitoje programoje, kad galėtumėte naudoti išskaidyto ekrano režimą"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dukart palieskite už programos ribų, kad pakeistumėte jos poziciją"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Supratau"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Išskleiskite, jei reikia daugiau informacijos."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Padidinti"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Sumažinti"</string> + <string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lt/strings_tv.xml b/libs/WindowManager/Shell/res/values-lt/strings_tv.xml index 04265ca01b48..52017dca2b94 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Vaizdas vaizde"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa be pavadinimo)"</string> - <string name="pip_close" msgid="9135220303720555525">"Uždaryti PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Uždaryti"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Visas ekranas"</string> - <string name="pip_move" msgid="1544227837964635439">"Perkelti PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Iškleisti PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Sutraukti PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Perkelti"</string> + <string name="pip_expand" msgid="1051966011679297308">"Išskleisti"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Sutraukti"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Jei reikia valdiklių, dukart paspauskite "<annotation icon="home_icon">"PAGRINDINIS"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Vaizdo vaizde meniu."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Perkelti kairėn"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Perkelti dešinėn"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Perkelti aukštyn"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Perkelti žemyn"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Atlikta"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index a77160bc262a..36743cfd171f 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Iestatījumi"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Piekļūt ekrāna sadalīšanas režīmam"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Izvēlne"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Izvēlne attēlam attēlā"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ir attēlā attēlā"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ja nevēlaties lietotnē <xliff:g id="NAME">%s</xliff:g> izmantot šo funkciju, pieskarieties, lai atvērtu iestatījumus un izslēgtu funkciju."</string> <string name="pip_play" msgid="3496151081459417097">"Atskaņot"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekrāna sadalītājs"</string> + <string name="divider_title" msgid="5482989479865361192">"Ekrāna sadalītājs"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Kreisā daļa pa visu ekrānu"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Pa kreisi 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pa kreisi 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Pieskarieties, lai restartētu šo lietotni un uzlabotu attēlojumu."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Vai ir problēmas ar kameru?\nPieskarieties, lai tās novērstu."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Dažas lietotnes vislabāk darbojas portreta režīmā"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Izmēģiniet vienu no šīm iespējām, lai efektīvi izmantotu pieejamo vietu"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pagrieziet ierīci, lai aktivizētu pilnekrāna režīmu"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Veiciet dubultskārienu blakus lietotnei, lai manītu tās pozīciju"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Uzziniet un paveiciet vairāk"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Lai izmantotu sadalītu ekrānu, ievelciet vēl vienu lietotni"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Lai pārvietotu lietotni, veiciet dubultskārienu ārpus lietotnes"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Labi"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Izvērsiet, lai iegūtu plašāku informāciju."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizēt"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizēt"</string> + <string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml index 8c6191e00833..11abac6f6197 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Attēls attēlā"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programma bez nosaukuma)"</string> - <string name="pip_close" msgid="9135220303720555525">"Aizvērt PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Aizvērt"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pilnekrāna režīms"</string> - <string name="pip_move" msgid="1544227837964635439">"Pārvietot attēlu attēlā"</string> - <string name="pip_expand" msgid="7605396312689038178">"Izvērst “Attēls attēlā” logu"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Sakļaut “Attēls attēlā” logu"</string> + <string name="pip_move" msgid="158770205886688553">"Pārvietot"</string> + <string name="pip_expand" msgid="1051966011679297308">"Izvērst"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Sakļaut"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Atvērt vadīklas: divreiz nospiediet pogu "<annotation icon="home_icon">"SĀKUMS"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Izvēlne attēlam attēlā."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Pārvietot pa kreisi"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Pārvietot pa labi"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Pārvietot augšup"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pārvietot lejup"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gatavs"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index bac0c9eee4c2..52a9377af22e 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Поставки"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Влези во поделен екран"</string> <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_play" msgid="3496151081459417097">"Пушти"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Разделник на поделен екран"</string> + <string name="divider_title" msgid="5482989479865361192">"Разделник на поделен екран"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Некои апликации најдобро работат во режим на портрет"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Испробајте една од опцииве за да го извлечете максимумот од вашиот простор"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ротирајте го уредот за да отворите на цел екран"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Допрете двапати до некоја апликација за да ја преместите"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Погледнете и направете повеќе"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Повлечете во друга апликација за поделен екран"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Зголеми"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Минимизирај"</string> + <string name="close_button_text" msgid="2913281996024033299">"Затвори"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mk/strings_tv.xml b/libs/WindowManager/Shell/res/values-mk/strings_tv.xml index beef1fef862b..21293223b882 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Слика во слика"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програма без наслов)"</string> - <string name="pip_close" msgid="9135220303720555525">"Затвори PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Затвори"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Цел екран"</string> - <string name="pip_move" msgid="1544227837964635439">"Премести PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Прошири ја сликата во слика"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Собери ја сликата во слика"</string> + <string name="pip_move" msgid="158770205886688553">"Премести"</string> + <string name="pip_expand" msgid="1051966011679297308">"Прошири"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Собери"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Притиснете двапати на "<annotation icon="home_icon">" HOME "</annotation>" за контроли"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Мени за „Слика во слика“."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Премести налево"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Премести надесно"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Премести нагоре"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Премести надолу"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index de0f837fcd3f..343ccf13427a 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ക്രമീകരണം"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"സ്ക്രീൻ വിഭജന മോഡിൽ പ്രവേശിക്കുക"</string> <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_play" msgid="3496151081459417097">"പ്ലേ ചെയ്യുക"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string> + <string name="divider_title" msgid="5482989479865361192">"സ്ക്രീൻ വിഭജന മോഡ് ഡിവൈഡർ"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ഈ ആപ്പ് റീസ്റ്റാർട്ട് ചെയ്ത് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ടാപ്പ് ചെയ്യുക."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ചില ആപ്പുകൾ പോർട്രെയ്റ്റിൽ മികച്ച രീതിയിൽ പ്രവർത്തിക്കുന്നു"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"നിങ്ങളുടെ ഇടം പരമാവധി പ്രയോജനപ്പെടുത്താൻ ഈ ഓപ്ഷനുകളിലൊന്ന് പരീക്ഷിക്കുക"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ഈ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ഒരു ആപ്പിന്റെ സ്ഥാനം മാറ്റാൻ, അതിന് തൊട്ടടുത്ത് ഡബിൾ ടാപ്പ് ചെയ്യുക"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"കൂടുതൽ കാണുക, ചെയ്യുക"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"സ്ക്രീൻ വിഭജന മോഡിന്, മറ്റൊരു ആപ്പ് വലിച്ചിടുക"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"വലുതാക്കുക"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ചെറുതാക്കുക"</string> + <string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ml/strings_tv.xml b/libs/WindowManager/Shell/res/values-ml/strings_tv.xml index c2a532d09647..549e39b21101 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ചിത്രത്തിനുള്ളിൽ ചിത്രം"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(പേരില്ലാത്ത പ്രോഗ്രാം)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP അടയ്ക്കുക"</string> + <string name="pip_close" msgid="2955969519031223530">"അടയ്ക്കുക"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"പൂര്ണ്ണ സ്ക്രീന്"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP നീക്കുക"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP വികസിപ്പിക്കുക"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP ചുരുക്കുക"</string> + <string name="pip_move" msgid="158770205886688553">"നീക്കുക"</string> + <string name="pip_expand" msgid="1051966011679297308">"വികസിപ്പിക്കുക"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ചുരുക്കുക"</string> <string name="pip_edu_text" msgid="3672999496647508701">" നിയന്ത്രണങ്ങൾക്കായി "<annotation icon="home_icon">" ഹോം "</annotation>" രണ്ട് തവണ അമർത്തുക"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ചിത്രത്തിനുള്ളിൽ ചിത്രം മെനു."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ഇടത്തേക്ക് നീക്കുക"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"വലത്തേക്ക് നീക്കുക"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"മുകളിലേക്ക് നീക്കുക"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"താഴേക്ക് നീക്കുക"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"പൂർത്തിയായി"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 1205306e0833..5370ef68dbd4 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Тохиргоо"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Хуваасан дэлгэцийг оруулна уу"</string> <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_play" msgid="3496151081459417097">"Тоглуулах"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"\"Дэлгэц хуваах\" хуваагч"</string> + <string name="divider_title" msgid="5482989479865361192">"\"Дэлгэцийг хуваах\" хуваагч"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Зарим апп нь босоо чиглэлд хамгийн сайн ажилладаг"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Орон зайгаа сайтар ашиглахын тулд эдгээр сонголтуудын аль нэгийг туршиж үзээрэй"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Төхөөрөмжөө бүтэн дэлгэцээр үзэхийн тулд эргүүлнэ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Аппыг дахин байрлуулахын тулд хажууд нь хоёр товшино"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Харж илүү ихийг хий"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Дэлгэцийг хуваахын тулд өөр апп руу чирнэ үү"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Томруулах"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Багасгах"</string> + <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mn/strings_tv.xml b/libs/WindowManager/Shell/res/values-mn/strings_tv.xml index bf8c59b57359..9a85d96ca602 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Дэлгэц доторх дэлгэц"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Гарчиггүй хөтөлбөр)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP-г хаах"</string> + <string name="pip_close" msgid="2955969519031223530">"Хаах"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Бүтэн дэлгэц"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP-г зөөх"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP-г дэлгэх"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP-г хураах"</string> + <string name="pip_move" msgid="158770205886688553">"Зөөх"</string> + <string name="pip_expand" msgid="1051966011679297308">"Дэлгэх"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Хураах"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Хяналтад хандах бол "<annotation icon="home_icon">" HOME "</annotation>" дээр хоёр дарна уу"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Дэлгэцэн доторх дэлгэцийн цэс."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Зүүн тийш зөөх"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Баруун тийш зөөх"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Дээш зөөх"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Доош зөөх"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Болсон"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index c91d06fdf3d5..1433ce4b0ab2 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग्ज"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन एंटर करा"</string> <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_play" msgid="3496151081459417097">"प्ले करा"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"विभाजित-स्क्रीन विभाजक"</string> + <string name="divider_title" msgid="5482989479865361192">"स्प्लिट-स्क्रीन विभाजक"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"हे अॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"काही ॲप्स पोर्ट्रेटमध्ये सर्वोत्तम काम करतात"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"तुमच्या स्पेसचा पुरेपूर वापर करण्यासाठी, यांपैकी एक पर्याय वापरून पहा"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"फुल स्क्रीन करण्यासाठी, तुमचे डिव्हाइस फिरवा"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ॲपची स्थिती पुन्हा बदलण्यासाठी, त्याच्या शेजारी दोनदा टॅप करा"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"पहा आणि आणखी बरेच काही करा"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"स्प्लिट-स्क्रीन वापरण्यासाठी दुसऱ्या ॲपमध्ये ड्रॅग करा"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"मोठे करा"</string> + <string name="minimize_button_text" msgid="271592547935841753">"लहान करा"</string> + <string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml index 5d519b7afe9a..a9779b3a3e89 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"चित्रात-चित्र"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(शीर्षक नसलेला कार्यक्रम)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP बंद करा"</string> + <string name="pip_close" msgid="2955969519031223530">"बंद करा"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"फुल स्क्रीन"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP हलवा"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP चा विस्तार करा"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP कोलॅप्स करा"</string> + <string name="pip_move" msgid="158770205886688553">"हलवा"</string> + <string name="pip_expand" msgid="1051966011679297308">"विस्तार करा"</string> + <string name="pip_collapse" msgid="3903295106641385962">"कोलॅप्स करा"</string> <string name="pip_edu_text" msgid="3672999496647508701">" नियंत्रणांसाठी "<annotation icon="home_icon">" होम "</annotation>" दोनदा दाबा"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"चित्रात-चित्र मेनू."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"डावीकडे हलवा"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"उजवीकडे हलवा"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"वर हलवा"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"खाली हलवा"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"पूर्ण झाले"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index 652a9919d163..04805dac59fe 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Tetapan"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk skrin pisah"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu Gambar dalam Gambar"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> terdapat dalam gambar dalam gambar"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikan ciri."</string> <string name="pip_play" msgid="3496151081459417097">"Main"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Apl mungkin tidak berfungsi pada paparan kedua."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Apl tidak menyokong pelancaran pada paparan kedua."</string> <string name="accessibility_divider" msgid="703810061635792791">"Pembahagi skrin pisah"</string> + <string name="divider_title" msgid="5482989479865361192">"Pembahagi skrin pisah"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Skrin penuh kiri"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kiri 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ketik untuk memulakan semula apl ini untuk mendapatkan paparan yang lebih baik."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Isu kamera?\nKetik untuk memuatkan semula"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sesetengah apl berfungsi paling baik dalam mod potret"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Cuba salah satu daripada pilihan ini untuk memanfaatkan ruang anda sepenuhnya"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Putar peranti anda untuk beralih ke skrin penuh"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ketik dua kali bersebelahan apl untuk menempatkan semula apl"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lihat dan lakukan lebih"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Seret apl lain untuk skrin pisah"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketik dua kali di luar apl untuk menempatkan semula apl itu"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kembangkan untuk mendapatkan maklumat lanjut."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimumkan"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimumkan"</string> + <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ms/strings_tv.xml b/libs/WindowManager/Shell/res/values-ms/strings_tv.xml index 08642c47c91a..8fe992d9f3b9 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Gambar dalam Gambar"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program tiada tajuk)"</string> - <string name="pip_close" msgid="9135220303720555525">"Tutup PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Tutup"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Skrin penuh"</string> - <string name="pip_move" msgid="1544227837964635439">"Alihkan PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Kembangkan PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Kuncupkan PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Alih"</string> + <string name="pip_expand" msgid="1051966011679297308">"Kembangkan"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Kuncupkan"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Tekan dua kali "<annotation icon="home_icon">" LAMAN UTAMA "</annotation>" untuk mengakses kawalan"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu Gambar dalam Gambar."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Alih ke kiri"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Alih ke kanan"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Alih ke atas"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Alih ke bawah"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Selesai"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 15d182c6451e..092cea20fb08 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ဆက်တင်များ"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသို့ ဝင်ရန်"</string> <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_play" msgid="3496151081459417097">"ဖွင့်ရန်"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string> + <string name="divider_title" msgid="5482989479865361192">"မျက်နှာပြင်ခွဲ၍ပြသသည့် စနစ်"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"ဘယ်ဘက် မျက်နှာပြင်အပြည့်"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ဘယ်ဘက်မျက်နှာပြင် ၇၀%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ဤအက်ပ်ကို ပြန်စပြီး ဖန်သားပြင်အပြည့်လုပ်ရန် တို့ပါ။"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"အချို့အက်ပ်များသည် ဒေါင်လိုက်တွင် အကောင်းဆုံးလုပ်ဆောင်သည်"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"သင့်နေရာကို အကောင်းဆုံးအသုံးပြုနိုင်ရန် ဤရွေးစရာများထဲမှ တစ်ခုကို စမ်းကြည့်ပါ"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ဖန်သားပြင်အပြည့်လုပ်ရန် သင့်စက်ကို လှည့်နိုင်သည်"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"အက်ပ်နေရာပြန်ချရန် ၎င်းဘေးတွင် နှစ်ချက်တို့နိုင်သည်"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ကြည့်ပြီး ပိုမိုလုပ်ဆောင်ပါ"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"မျက်နှာပြင် ခွဲ၍ပြသနိုင်ရန် နောက်အက်ပ်တစ်ခုကို ဖိဆွဲပါ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ချဲ့ရန်"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ချုံ့ရန်"</string> + <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-my/strings_tv.xml b/libs/WindowManager/Shell/res/values-my/strings_tv.xml index e01daee115ca..105628d8149e 100644 --- a/libs/WindowManager/Shell/res/values-my/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-my/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"နှစ်ခုထပ်၍ကြည့်ခြင်း"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ခေါင်းစဉ်မဲ့ အစီအစဉ်)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP ကိုပိတ်ပါ"</string> + <string name="pip_close" msgid="2955969519031223530">"ပိတ်ရန်"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"မျက်နှာပြင် အပြည့်"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP ရွှေ့ရန်"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP ကို ချဲ့ရန်"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP ကို လျှော့ပြပါ"</string> + <string name="pip_move" msgid="158770205886688553">"ရွှေ့ရန်"</string> + <string name="pip_expand" msgid="1051966011679297308">"ချဲ့ရန်"</string> + <string name="pip_collapse" msgid="3903295106641385962">"လျှော့ပြရန်"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ထိန်းချုပ်မှုအတွက် "<annotation icon="home_icon">" ပင်မခလုတ် "</annotation>" နှစ်ချက်နှိပ်ပါ"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"နှစ်ခုထပ်၍ ကြည့်ခြင်းမီနူး။"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ဘယ်သို့ရွှေ့ရန်"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ညာသို့ရွှေ့ရန်"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"အပေါ်သို့ရွှေ့ရန်"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"အောက်သို့ရွှေ့ရန်"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ပြီးပြီ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 9fd42b2f129c..22fa7f2efafc 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Innstillinger"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivér delt skjerm"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Bilde-i-bilde-meny"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er i bilde-i-bilde"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Hvis du ikke vil at <xliff:g id="NAME">%s</xliff:g> skal bruke denne funksjonen, kan du trykke for å åpne innstillingene og slå den av."</string> <string name="pip_play" msgid="3496151081459417097">"Spill av"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer kanskje ikke på en sekundær skjerm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke kjøres på sekundære skjermer."</string> <string name="accessibility_divider" msgid="703810061635792791">"Skilleelement for delt skjerm"</string> + <string name="divider_title" msgid="5482989479865361192">"Skilleelement for delt skjerm"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Utvid den venstre delen av skjermen til hele skjermen"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Sett størrelsen på den venstre delen av skjermen til 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string> @@ -63,7 +65,7 @@ <string name="bubble_dismiss_text" msgid="8816558050659478158">"Lukk boblen"</string> <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ikke vis samtaler i bobler"</string> <string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat med bobler"</string> - <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nye samtaler vises som flytende ikoner eller bobler. Trykk for å åpne bobler. Dra for å flytte dem."</string> + <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nye samtaler vises som flytende ikoner eller bobler. Trykk for å åpne en boble. Dra for å flytte den."</string> <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Kontrollér bobler når som helst"</string> <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Trykk på Administrer for å slå av bobler for denne appen"</string> <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Greit"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Trykk for å starte denne appen på nytt for bedre visning."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du kameraproblemer?\nTrykk for å tilpasse"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Noen apper fungerer best i stående format"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prøv et av disse alternativene for å få mest mulig ut av plassen din"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Roter enheten for å starte fullskjerm"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dobbelttrykk ved siden av en app for å flytte den"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se og gjør mer"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Dra inn en annen app for å bruke delt skjerm"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dobbelttrykk utenfor en app for å flytte den"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Greit"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vis for å få mer informasjon."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimer"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string> + <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml index 65ed0b7f5bff..ca63518df7a5 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Bilde-i-bilde"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program uten tittel)"</string> - <string name="pip_close" msgid="9135220303720555525">"Lukk PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Lukk"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Fullskjerm"</string> - <string name="pip_move" msgid="1544227837964635439">"Flytt BIB"</string> - <string name="pip_expand" msgid="7605396312689038178">"Vis BIB"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Skjul BIB"</string> + <string name="pip_move" msgid="158770205886688553">"Flytt"</string> + <string name="pip_expand" msgid="1051966011679297308">"Vis"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Skjul"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Dobbelttrykk på "<annotation icon="home_icon">"HJEM"</annotation>" for å åpne kontroller"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Bilde-i-bilde-meny."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Flytt til venstre"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Flytt til høyre"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Flytt opp"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Flytt ned"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Ferdig"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 8dfec88cc29d..9502421e46b6 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिङहरू"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रिन मोड प्रयोग गर्नुहोस्"</string> <string name="pip_menu_title" msgid="5393619322111827096">"मेनु"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"\"picture-in-picture\" मेनु"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> Picture-in-picture मा छ"</string> <string name="pip_notification_message" msgid="8854051911700302620">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले सुविधा प्रयोग नगरोस् भन्ने चाहनुहुन्छ भने ट्याप गरेर सेटिङहरू खोल्नुहोस् र यसलाई निष्क्रिय पार्नुहोस्।"</string> <string name="pip_play" msgid="3496151081459417097">"प्ले गर्नुहोस्"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string> + <string name="divider_title" msgid="5482989479865361192">"स्प्लिट स्क्रिन डिभाइडर"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"बायाँ भाग फुल स्क्रिन"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"बायाँ भाग ७०%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बायाँ भाग ५०%"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"केही एपहरूले पोर्ट्रेटमा राम्रोसँग काम गर्छन्"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"तपाईं स्क्रिनको अधिकतम ठाउँ प्रयोग गर्न चाहनुहुन्छ भने यीमध्ये कुनै विकल्प प्रयोग गरी हेर्नुहोस्"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"तपाईं फुल स्क्रिन मोड हेर्न चाहनुहुन्छ भने आफ्नो डिभाइस रोटेट गर्नुहोस्"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"तपाईं जुन एपको स्थिति मिलाउन चाहनुहुन्छ सोही एपको छेउमा डबल ट्याप गर्नुहोस्"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"थप कुरा हेर्नुहोस् र गर्नुहोस्"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"स्प्लिट स्क्रिन मोड प्रयोग गर्न अर्को एप ड्रयाग एन्ड ड्रप गर्नुहोस्"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ठुलो बनाउनुहोस्"</string> + <string name="minimize_button_text" msgid="271592547935841753">"मिनिमाइज गर्नुहोस्"</string> + <string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ne/strings_tv.xml b/libs/WindowManager/Shell/res/values-ne/strings_tv.xml index d33fed67efb6..7cbf9e294e7b 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-Picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(शीर्षकविहीन कार्यक्रम)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP लाई बन्द गर्नुहोस्"</string> + <string name="pip_close" msgid="2955969519031223530">"बन्द गर्नुहोस्"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"फुल स्क्रिन"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP सार्नुहोस्"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP विन्डो एक्स्पान्ड गर्नु…"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP विन्डो कोल्याप्स गर्नुहोस्"</string> + <string name="pip_move" msgid="158770205886688553">"सार्नुहोस्"</string> + <string name="pip_expand" msgid="1051966011679297308">"एक्स्पान्ड गर्नुहोस्"</string> + <string name="pip_collapse" msgid="3903295106641385962">"कोल्याप्स गर्नुहोस्"</string> <string name="pip_edu_text" msgid="3672999496647508701">" कन्ट्रोल मेनु खोल्न "<annotation icon="home_icon">" होम "</annotation>" बटन दुई पटक थिच्नुहोस्"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"\"picture-in-picture\" मेनु।"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"बायाँतिर सार्नुहोस्"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"दायाँतिर सार्नुहोस्"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"माथितिर सार्नुहोस्"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"तलतिर सार्नुहोस्"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"सम्पन्न भयो"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index 8468b04c66da..37fe1fd2b3ed 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Instellingen"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Gesplitst scherm openen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Scherm-in-scherm-menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in scherm-in-scherm"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Als je niet wilt dat <xliff:g id="NAME">%s</xliff:g> deze functie gebruikt, tik je om de instellingen te openen en zet je de functie uit."</string> <string name="pip_play" msgid="3496151081459417097">"Afspelen"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App werkt mogelijk niet op een secundair scherm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App kan niet op secundaire displays worden gestart."</string> <string name="accessibility_divider" msgid="703810061635792791">"Scheiding voor gesplitst scherm"</string> + <string name="divider_title" msgid="5482989479865361192">"Scheiding voor gesplitst scherm"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Linkerscherm op volledig scherm"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Linkerscherm 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Linkerscherm 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tik om deze app opnieuw op te starten voor een betere weergave."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Cameraproblemen?\nTik om opnieuw passend te maken."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sommige apps werken het best in de staande stand"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Probeer een van deze opties om optimaal gebruik te maken van je ruimte"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Draai je apparaat om naar volledig scherm te schakelen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dubbeltik naast een app om deze opnieuw te positioneren"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zie en doe meer"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Sleep een andere app hier naartoe om het scherm te splitsen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dubbeltik naast een app om deze opnieuw te positioneren"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Uitvouwen voor meer informatie."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximaliseren"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimaliseren"</string> + <string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nl/strings_tv.xml b/libs/WindowManager/Shell/res/values-nl/strings_tv.xml index 9763c5665ab2..2deaeddc4080 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Scherm-in-scherm"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Naamloos programma)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP sluiten"</string> + <string name="pip_close" msgid="2955969519031223530">"Sluiten"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Volledig scherm"</string> - <string name="pip_move" msgid="1544227837964635439">"SIS verplaatsen"</string> - <string name="pip_expand" msgid="7605396312689038178">"SIS uitvouwen"</string> - <string name="pip_collapse" msgid="5732233773786896094">"SIS samenvouwen"</string> + <string name="pip_move" msgid="158770205886688553">"Verplaatsen"</string> + <string name="pip_expand" msgid="1051966011679297308">"Uitvouwen"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Samenvouwen"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Druk twee keer op "<annotation icon="home_icon">" HOME "</annotation>" voor bedieningselementen"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Scherm-in-scherm-menu."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Naar links verplaatsen"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Naar rechts verplaatsen"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Omhoog verplaatsen"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Omlaag verplaatsen"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Klaar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index a8d8448edf99..ca31f3cf84a7 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ସେଟିଂସ୍"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ମୋଡ ବ୍ୟବହାର କରନ୍ତୁ"</string> <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_play" msgid="3496151081459417097">"ପ୍ଲେ କରନ୍ତୁ"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string> + <string name="divider_title" msgid="5482989479865361192">"ସ୍ପ୍ଲିଟ-ସ୍କ୍ରିନ ଡିଭାଇଡର"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ଏହି ଆପକୁ ରିଷ୍ଟାର୍ଟ କରି ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"କିଛି ଆପ ପୋର୍ଟ୍ରେଟରେ ସବୁଠାରୁ ଭଲ କାମ କରେ"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ଆପଣଙ୍କ ସ୍ପେସରୁ ଅଧିକ ଲାଭ ପାଇବାକୁ ଏହି ବିକଳ୍ପଗୁଡ଼ିକ ମଧ୍ୟରୁ ଗୋଟିଏ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ପୂର୍ଣ୍ଣ-ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ରୋଟେଟ କରନ୍ତୁ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହା ପାଖରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ଦେଖନ୍ତୁ ଏବଂ ଆହୁରି ଅନେକ କିଛି କରନ୍ତୁ"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ସ୍ପ୍ଲିଟ-ସ୍କ୍ରିନ ପାଇଁ ଅନ୍ୟ ଏକ ଆପକୁ ଡ୍ରାଗ କରନ୍ତୁ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ବଡ଼ କରନ୍ତୁ"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ଛୋଟ କରନ୍ତୁ"</string> + <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-or/strings_tv.xml b/libs/WindowManager/Shell/res/values-or/strings_tv.xml index e0344855bd1f..0c1d99e4ca71 100644 --- a/libs/WindowManager/Shell/res/values-or/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-or/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ପିକଚର୍-ଇନ୍-ପିକଚର୍"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(କୌଣସି ଟାଇଟଲ୍ ପ୍ରୋଗ୍ରାମ୍ ନାହିଁ)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP ବନ୍ଦ କରନ୍ତୁ"</string> + <string name="pip_close" msgid="2955969519031223530">"ବନ୍ଦ କରନ୍ତୁ"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍"</string> - <string name="pip_move" msgid="1544227837964635439">"PIPକୁ ମୁଭ କରନ୍ତୁ"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIPକୁ ବିସ୍ତାର କରନ୍ତୁ"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIPକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string> + <string name="pip_move" msgid="158770205886688553">"ମୁଭ କରନ୍ତୁ"</string> + <string name="pip_expand" msgid="1051966011679297308">"ବିସ୍ତାର କରନ୍ତୁ"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ସଙ୍କୁଚିତ କରନ୍ତୁ"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ପାଇଁ "<annotation icon="home_icon">" ହୋମ ବଟନ "</annotation>"କୁ ଦୁଇଥର ଦବାନ୍ତୁ"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ପିକଚର-ଇନ-ପିକଚର ମେନୁ।"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ବାମକୁ ମୁଭ କରନ୍ତୁ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ଉପରକୁ ମୁଭ କରନ୍ତୁ"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ତଳକୁ ମୁଭ କରନ୍ତୁ"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ହୋଇଗଲା"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index f99176cb682d..1f118c901243 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ਸੈਟਿੰਗਾਂ"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string> <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_play" msgid="3496151081459417097">"ਚਲਾਓ"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string> + <string name="divider_title" msgid="5482989479865361192">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਵਿਭਾਜਕ"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ਕੁਝ ਐਪਾਂ ਪੋਰਟਰੇਟ ਵਿੱਚ ਬਿਹਤਰ ਕੰਮ ਕਰਦੀਆਂ ਹਨ"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ਆਪਣੀ ਜਗ੍ਹਾ ਦਾ ਵੱਧ ਤੋਂ ਵੱਧ ਲਾਹਾ ਲੈਣ ਲਈ ਇਨ੍ਹਾਂ ਵਿਕਲਪਾਂ ਵਿੱਚੋਂ ਕੋਈ ਇੱਕ ਵਰਤ ਕੇ ਦੇਖੋ"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਣ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁਮਾਓ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਅੱਗੇ ਡਬਲ ਟੈਪ ਕਰੋ"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ਦੇਖੋ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਕਰੋ"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੇ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ ਵਿੱਚ ਘਸੀਟੋ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ਵੱਡਾ ਕਰੋ"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ਛੋਟਾ ਕਰੋ"</string> + <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pa/strings_tv.xml b/libs/WindowManager/Shell/res/values-pa/strings_tv.xml index 9c01ac3f3cc0..a1edde738775 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ਸਿਰਲੇਖ-ਰਹਿਤ ਪ੍ਰੋਗਰਾਮ)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP ਬੰਦ ਕਰੋ"</string> + <string name="pip_close" msgid="2955969519031223530">"ਬੰਦ ਕਰੋ"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP ਨੂੰ ਲਿਜਾਓ"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP ਨੂੰ ਸਮੇਟੋ"</string> + <string name="pip_move" msgid="158770205886688553">"ਲਿਜਾਓ"</string> + <string name="pip_expand" msgid="1051966011679297308">"ਵਿਸਤਾਰ ਕਰੋ"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ਸਮੇਟੋ"</string> <string name="pip_edu_text" msgid="3672999496647508701">" ਕੰਟਰੋਲਾਂ ਲਈ "<annotation icon="home_icon">" ਹੋਮ ਬਟਨ "</annotation>" ਨੂੰ ਦੋ ਵਾਰ ਦਬਾਓ"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ ਮੀਨੂ।"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ਖੱਬੇ ਲਿਜਾਓ"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ਸੱਜੇ ਲਿਜਾਓ"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ਉੱਪਰ ਲਿਜਾਓ"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ਹੇਠਾਂ ਲਿਜਾਓ"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ਹੋ ਗਿਆ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index f2147c04d335..4171aebcf99a 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Ustawienia"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Włącz podzielony ekran"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu funkcji Obraz w obrazie."</string> <string name="pip_notification_title" msgid="1347104727641353453">"Aplikacja <xliff:g id="NAME">%s</xliff:g> działa w trybie obraz w obrazie"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Jeśli nie chcesz, by aplikacja <xliff:g id="NAME">%s</xliff:g> korzystała z tej funkcji, otwórz ustawienia i wyłącz ją."</string> <string name="pip_play" msgid="3496151081459417097">"Odtwórz"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacja może nie działać na dodatkowym ekranie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string> <string name="accessibility_divider" msgid="703810061635792791">"Linia dzielenia ekranu"</string> + <string name="divider_title" msgid="5482989479865361192">"Linia dzielenia ekranu"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lewa część ekranu na pełnym ekranie"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% lewej części ekranu"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% lewej części ekranu"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string> - <string name="restart_button_description" msgid="5887656107651190519">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Kliknij, aby zrestartować aplikację i zyskać lepszą widoczność."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemy z aparatem?\nKliknij, aby dopasować"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Naprawa się nie udała?\nKliknij, aby cofnąć"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Brak problemów z aparatem? Kliknij, aby zamknąć"</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Niektóre aplikacje działają najlepiej w orientacji pionowej"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Wypróbuj jedną z tych opcji, aby jak najlepiej wykorzystać miejsce"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Obróć urządzenie, aby przejść do pełnego ekranu"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Kliknij dwukrotnie obok aplikacji, aby ją przenieść"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zobacz i zrób więcej"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Przeciągnij drugą aplikację, aby podzielić ekran"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kliknij dwukrotnie poza aplikacją, aby ją przenieść"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozwiń, aby wyświetlić więcej informacji."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksymalizuj"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimalizuj"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml index b922e2d5a6ba..2bb90addc241 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Obraz w obrazie"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez tytułu)"</string> - <string name="pip_close" msgid="9135220303720555525">"Zamknij PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Zamknij"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Pełny ekran"</string> - <string name="pip_move" msgid="1544227837964635439">"Przenieś PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Rozwiń PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Zwiń PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Przenieś"</string> + <string name="pip_expand" msgid="1051966011679297308">"Rozwiń"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Zwiń"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Naciśnij dwukrotnie "<annotation icon="home_icon">"EKRAN GŁÓWNY"</annotation>", aby wyświetlić ustawienia"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu funkcji Obraz w obrazie."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Przenieś w lewo"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Przenieś w prawo"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Przenieś w górę"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Przenieś w dół"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gotowe"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index 2efc5543dd87..7a62410ad125 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu do picture-in-picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Se você não quer que o app <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string> <string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string> + <string name="divider_title" msgid="5482989479865361192">"Divisor de tela"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lado esquerdo em tela cheia"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Esquerda a 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Alguns apps funcionam melhor em modo retrato"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Tente uma destas opções para aproveitar seu espaço ao máximo"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gire o dispositivo para entrar no modo de tela cheia"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes ao lado de um app para reposicionar"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arraste outro app para a tela dividida"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de um app para reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> + <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml index cc4eb3c32c1f..14d1c34fd3e8 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(programa sem título)"</string> - <string name="pip_close" msgid="9135220303720555525">"Fechar PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Fechar"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Tela cheia"</string> - <string name="pip_move" msgid="1544227837964635439">"Mover picture-in-picture"</string> - <string name="pip_expand" msgid="7605396312689038178">"Abrir picture-in-picture"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Fechar picture-in-picture"</string> + <string name="pip_move" msgid="158770205886688553">"Mover"</string> + <string name="pip_expand" msgid="1051966011679297308">"Abrir"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Fechar"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Pressione o botão "<annotation icon="home_icon">"home"</annotation>" duas vezes para acessar os controles"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu do picture-in-picture"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover para a esquerda"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover para a direita"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover para cima"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover para baixo"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Concluído"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index c68a6934dead..00549026483f 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Definições"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aceder ao ecrã dividido"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu de ecrã no ecrã"</string> <string name="pip_notification_title" msgid="1347104727641353453">"A app <xliff:g id="NAME">%s</xliff:g> está no modo de ecrã no ecrã"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Se não pretende que a app <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string> <string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"A app pode não funcionar num ecrã secundário."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A app não é compatível com o início em ecrãs secundários."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor do ecrã dividido"</string> + <string name="divider_title" msgid="5482989479865361192">"Divisor do ecrã dividido"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ecrã esquerdo inteiro"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"70% no ecrã esquerdo"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% no ecrã esquerdo"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ficar com uma melhor visão."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algumas apps funcionam melhor no modo vertical"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Experimente uma destas opções para aproveitar ao máximo o seu espaço"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rode o dispositivo para ficar em ecrã inteiro"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes junto a uma app para a reposicionar"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arraste outra app para usar o ecrã dividido"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de uma app para a reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expandir para obter mais informações"</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> + <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml index c4ae78d89ba8..1ada4508714a 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Ecrã no ecrã"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Sem título do programa)"</string> - <string name="pip_close" msgid="9135220303720555525">"Fechar PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Fechar"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Ecrã inteiro"</string> - <string name="pip_move" msgid="1544227837964635439">"Mover Ecrã no ecrã"</string> - <string name="pip_expand" msgid="7605396312689038178">"Expandir Ecrã no ecrã"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Reduzir Ecrã no ecrã"</string> + <string name="pip_move" msgid="158770205886688553">"Mover"</string> + <string name="pip_expand" msgid="1051966011679297308">"Expandir"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Reduzir"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Prima duas vezes "<annotation icon="home_icon">" PÁGINA INICIAL "</annotation>" para controlos"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu de ecrã no ecrã."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover para a esquerda"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover para a direita"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover para cima"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover para baixo"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Concluído"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index 2efc5543dd87..7a62410ad125 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu do picture-in-picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Se você não quer que o app <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string> <string name="pip_play" msgid="3496151081459417097">"Reproduzir"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divisor de tela"</string> + <string name="divider_title" msgid="5482989479865361192">"Divisor de tela"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Lado esquerdo em tela cheia"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Esquerda a 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Alguns apps funcionam melhor em modo retrato"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Tente uma destas opções para aproveitar seu espaço ao máximo"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gire o dispositivo para entrar no modo de tela cheia"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes ao lado de um app para reposicionar"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Arraste outro app para a tela dividida"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de um app para reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> + <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt/strings_tv.xml index cc4eb3c32c1f..14d1c34fd3e8 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(programa sem título)"</string> - <string name="pip_close" msgid="9135220303720555525">"Fechar PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Fechar"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Tela cheia"</string> - <string name="pip_move" msgid="1544227837964635439">"Mover picture-in-picture"</string> - <string name="pip_expand" msgid="7605396312689038178">"Abrir picture-in-picture"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Fechar picture-in-picture"</string> + <string name="pip_move" msgid="158770205886688553">"Mover"</string> + <string name="pip_expand" msgid="1051966011679297308">"Abrir"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Fechar"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Pressione o botão "<annotation icon="home_icon">"home"</annotation>" duas vezes para acessar os controles"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu do picture-in-picture"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mover para a esquerda"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mover para a direita"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mover para cima"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mover para baixo"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Concluído"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 804d34f980ff..352f81b7b6f0 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -17,25 +17,27 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="pip_phone_close" msgid="5783752637260411309">"Închideți"</string> - <string name="pip_phone_expand" msgid="2579292903468287504">"Extindeți"</string> + <string name="pip_phone_close" msgid="5783752637260411309">"Închide"</string> + <string name="pip_phone_expand" msgid="2579292903468287504">"Extinde"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Setări"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accesați ecranul împărțit"</string> + <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accesează ecranul împărțit"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meniu picture-in-picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> este în modul picture-in-picture"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Dacă nu doriți ca <xliff:g id="NAME">%s</xliff:g> să utilizeze această funcție, atingeți pentru a deschide setările și dezactivați-o."</string> - <string name="pip_play" msgid="3496151081459417097">"Redați"</string> - <string name="pip_pause" msgid="690688849510295232">"Întrerupeți"</string> + <string name="pip_play" msgid="3496151081459417097">"Redă"</string> + <string name="pip_pause" msgid="690688849510295232">"Întrerupe"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"Treceți la următorul"</string> <string name="pip_skip_to_prev" msgid="7172158111196394092">"Treceți la cel anterior"</string> <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Redimensionați"</string> <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Stocați"</string> - <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Anulați stocarea"</string> + <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Anulează stocarea"</string> <string name="dock_forced_resizable" msgid="1749750436092293116">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"Aplicația nu acceptă ecranul împărțit."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplicația nu acceptă lansare pe ecrane secundare."</string> <string name="accessibility_divider" msgid="703810061635792791">"Separator pentru ecranul împărțit"</string> + <string name="divider_title" msgid="5482989479865361192">"Separator pentru ecranul împărțit"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Partea stângă pe ecran complet"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Partea stângă: 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Partea stângă: 50%"</string> @@ -48,19 +50,19 @@ <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Partea de jos pe ecran complet"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Folosirea modului cu o mână"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pentru a ieși, glisați în sus din partea de jos a ecranului sau atingeți oriunde deasupra ferestrei aplicației"</string> - <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Activați modul cu o mână"</string> + <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Activează modul cu o mână"</string> <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Părăsiți modul cu o mână"</string> <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Setări pentru baloanele <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Suplimentar"</string> - <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Adăugați înapoi în stivă"</string> + <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Adaugă înapoi în stivă"</string> <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de la <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> de la <xliff:g id="APP_NAME">%2$s</xliff:g> și încă <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string> - <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Mutați în stânga sus"</string> - <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Mutați în dreapta sus"</string> - <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Mutați în stânga jos"</string> - <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mutați în dreapta jos"</string> + <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"Mută în stânga sus"</string> + <string name="bubble_accessibility_action_move_top_right" msgid="5864594920870245525">"Mută în dreapta sus"</string> + <string name="bubble_accessibility_action_move_bottom_left" msgid="850271002773745634">"Mută în stânga jos"</string> + <string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mută în dreapta jos"</string> <string name="bubbles_app_settings" msgid="3617224938701566416">"Setări <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> - <string name="bubble_dismiss_text" msgid="8816558050659478158">"Închideți balonul"</string> + <string name="bubble_dismiss_text" msgid="8816558050659478158">"Închide balonul"</string> <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nu afișați conversația în balon"</string> <string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat cu baloane"</string> <string name="bubbles_user_education_description" msgid="4215862563054175407">"Conversațiile noi apar ca pictograme flotante sau baloane. Atingeți pentru a deschide balonul. Trageți pentru a-l muta."</string> @@ -70,15 +72,18 @@ <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nu există baloane recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Baloanele recente și baloanele respinse vor apărea aici"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> - <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionați"</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="5887656107651190519">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Atingeți ca să reporniți aplicația pentru o vizualizare mai bună."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Aveți probleme cu camera foto?\nAtingeți pentru a reîncadra"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ați remediat problema?\nAtingeți pentru a reveni"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu aveți probleme cu camera foto? Atingeți pentru a închide."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Unele aplicații funcționează cel mai bine în orientarea portret"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Încercați una dintre aceste opțiuni pentru a profita din plin de spațiu"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotiți dispozitivul pentru a trece în modul ecran complet"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Atingeți de două ori lângă o aplicație pentru a o repoziționa"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vezi și fă mai multe"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Trage în altă aplicație pentru a folosi ecranul împărțit"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Atinge de două ori lângă o aplicație pentru a o repoziționa"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Extinde pentru mai multe informații"</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximizați"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizează"</string> + <string name="close_button_text" msgid="2913281996024033299">"Închide"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml index 86a30f49df15..36df2864a752 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program fără titlu)"</string> - <string name="pip_close" msgid="9135220303720555525">"Închideți PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Închide"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Ecran complet"</string> - <string name="pip_move" msgid="1544227837964635439">"Mutați fereastra PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Extindeți fereastra PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Restrângeți fereastra PIP"</string> - <string name="pip_edu_text" msgid="3672999496647508701">" Apăsați de două ori "<annotation icon="home_icon">"butonul ecran de pornire"</annotation>" pentru comenzi"</string> + <string name="pip_move" msgid="158770205886688553">"Mută"</string> + <string name="pip_expand" msgid="1051966011679297308">"Extinde"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Restrânge"</string> + <string name="pip_edu_text" msgid="3672999496647508701">" Apasă de două ori "<annotation icon="home_icon">"butonul ecran de pornire"</annotation>" pentru comenzi"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meniu picture-in-picture."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mută spre stânga"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mută spre dreapta"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mută în sus"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mută în jos"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gata"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index 95bf1cf11435..1a77e428ccf3 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Включить разделение экрана"</string> <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_play" msgid="3496151081459417097">"Воспроизвести"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Разделитель экрана"</string> + <string name="divider_title" msgid="5482989479865361192">"Разделитель экрана"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Некоторые приложения лучше работают в вертикальном режиме"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Чтобы эффективно использовать экранное пространство, выполните одно из следующих действий:"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Чтобы перейти в полноэкранный режим, поверните устройство."</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Чтобы переместить приложение, нажмите на него дважды."</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Выполняйте несколько задач одновременно"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Перетащите сюда другое приложение, чтобы использовать разделение экрана."</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Развернуть"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Свернуть"</string> + <string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ru/strings_tv.xml b/libs/WindowManager/Shell/res/values-ru/strings_tv.xml index 08623e1e69c5..e7f55ec1bc57 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Картинка в картинке"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Без названия)"</string> - <string name="pip_close" msgid="9135220303720555525">"\"Кадр в кадре\" – выйти"</string> + <string name="pip_close" msgid="2955969519031223530">"Закрыть"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Во весь экран"</string> - <string name="pip_move" msgid="1544227837964635439">"Переместить PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Развернуть PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Свернуть PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Переместить"</string> + <string name="pip_expand" msgid="1051966011679297308">"Развернуть"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Свернуть"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Элементы управления: дважды нажмите "<annotation icon="home_icon">" кнопку главного экрана "</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню \"Картинка в картинке\"."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Переместить влево"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Переместить вправо"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Переместить вверх"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Переместить вниз"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 23dd65ad7b31..dc89ec3a836c 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"සැකසීම්"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"බෙදුම් තිරයට ඇතුළු වන්න"</string> <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_play" msgid="3496151081459417097">"ධාවනය කරන්න"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"බෙදුම්-තිර වෙන්කරණය"</string> + <string name="divider_title" msgid="5482989479865361192">"බෙදුම්-තිර වෙන්කරණය"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"සමහර යෙදුම් ප්රතිමූර්තිය තුළ හොඳින්ම ක්රියා කරයි"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ඔබගේ ඉඩෙන් උපරිම ප්රයෝජන ගැනීමට මෙම විකල්පවලින් එකක් උත්සාහ කරන්න"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"සම්පූර්ණ තිරයට යාමට ඔබගේ උපාංගය කරකවන්න"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"එය නැවත ස්ථානගත කිරීමට යෙදුමකට යාබදව දෙවරක් තට්ටු කරන්න"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"බලන්න සහ තවත් දේ කරන්න"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"බෙදුම් තිරය සඳහා වෙනත් යෙදුමකට අදින්න"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"විහිදන්න"</string> + <string name="minimize_button_text" msgid="271592547935841753">"කුඩා කරන්න"</string> + <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-si/strings_tv.xml b/libs/WindowManager/Shell/res/values-si/strings_tv.xml index fbb0ebba0623..5478ce5d3d40 100644 --- a/libs/WindowManager/Shell/res/values-si/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-si/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"පින්තූරය-තුළ-පින්තූරය"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(මාතෘකාවක් නැති වැඩසටහන)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP වසන්න"</string> + <string name="pip_close" msgid="2955969519031223530">"වසන්න"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"සම්පූර්ණ තිරය"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP ගෙන යන්න"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP දිග හරින්න"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP හකුළන්න"</string> + <string name="pip_move" msgid="158770205886688553">"ගෙන යන්න"</string> + <string name="pip_expand" msgid="1051966011679297308">"දිග හරින්න"</string> + <string name="pip_collapse" msgid="3903295106641385962">"හකුළන්න"</string> <string name="pip_edu_text" msgid="3672999496647508701">" පාලන සඳහා "<annotation icon="home_icon">" මුල් පිටුව "</annotation>" දෙවරක් ඔබන්න"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"පින්තූරය තුළ පින්තූරය මෙනුව"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"වමට ගෙන යන්න"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"දකුණට ගෙන යන්න"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ඉහළට ගෙන යන්න"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"පහළට ගෙන යන්න"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"නිමයි"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index a231cacefb20..aec8501fca23 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavenia"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Prejsť na rozdelenú obrazovku"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Ponuka"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Ponuka obrazu v obraze"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v režime obraz v obraze"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ak nechcete, aby aplikácia <xliff:g id="NAME">%s</xliff:g> používala túto funkciu, klepnutím otvorte nastavenia a vypnite ju."</string> <string name="pip_play" msgid="3496151081459417097">"Prehrať"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string> <string name="accessibility_divider" msgid="703810061635792791">"Rozdeľovač obrazovky"</string> + <string name="divider_title" msgid="5482989479865361192">"Rozdeľovač obrazovky"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ľavá – na celú obrazovku"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Ľavá – 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ľavá – 50 %"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ak chcete zlepšiť zobrazenie, klepnutím túto aplikáciu reštartujte."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s kamerou?\nKlepnutím znova upravte."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Niektoré aplikácie fungujú najlepšie v režime na výšku"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Vyskúšajte jednu z týchto možností a využívajte svoj priestor naplno"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Otočením zariadenia prejdete do režimu celej obrazovky"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvojitým klepnutím vedľa aplikácie zmeníte jej pozíciu"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zobrazte si a zvládnite toho viac"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Rozdelenú obrazovku aktivujete presunutím ďalšie aplikácie"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikácie zmeníte jej pozíciu"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Dobre"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Po rozbalení sa dozviete viac."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovať"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovať"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sk/strings_tv.xml b/libs/WindowManager/Shell/res/values-sk/strings_tv.xml index 81cb0eafc759..1df43afca2da 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Obraz v obraze"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program bez názvu)"</string> - <string name="pip_close" msgid="9135220303720555525">"Zavrieť režim PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Zavrieť"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Celá obrazovka"</string> - <string name="pip_move" msgid="1544227837964635439">"Presunúť obraz v obraze"</string> - <string name="pip_expand" msgid="7605396312689038178">"Rozbaliť obraz v obraze"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Zbaliť obraz v obraze"</string> + <string name="pip_move" msgid="158770205886688553">"Presunúť"</string> + <string name="pip_expand" msgid="1051966011679297308">"Rozbaliť"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Zbaliť"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Ovládanie zobraz. dvoj. stlač. "<annotation icon="home_icon">" TLAČIDLA PLOCHY "</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Ponuka obrazu v obraze."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Posunúť doľava"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Posunúť doprava"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Posunúť nahor"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Posunúť nadol"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Hotovo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index adeaae978eaa..44462b6edb04 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavitve"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Vklopi razdeljen zaslon"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meni za sliko v sliki"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v načinu slika v sliki"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Če ne želite, da aplikacija <xliff:g id="NAME">%s</xliff:g> uporablja to funkcijo, se dotaknite, da odprete nastavitve, in funkcijo izklopite."</string> <string name="pip_play" msgid="3496151081459417097">"Predvajaj"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string> <string name="accessibility_divider" msgid="703810061635792791">"Razdelilnik zaslonov"</string> + <string name="divider_title" msgid="5482989479865361192">"Razdelilnik zaslonov"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Levi v celozaslonski način"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Levi 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi 50 %"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Če želite boljši prikaz, se dotaknite za vnovični zagon te aplikacije."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Težave s fotoaparatom?\nDotaknite se za vnovično prilagoditev"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Nekatere aplikacije najbolje delujejo v navpični postavitvi"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Poskusite eno od teh možnosti za čim boljši izkoristek prostora"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Če želite preklopiti v celozaslonski način, zasukajte napravo."</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvakrat se dotaknite ob aplikaciji, če jo želite prestaviti."</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Oglejte si in naredite več"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Za razdeljeni zaslon povlecite sem še eno aplikacijo."</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvakrat se dotaknite zunaj aplikacije, če jo želite prestaviti."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"V redu"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Razširitev za več informacij"</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiraj"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimiraj"</string> + <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml index 060aaa0ce647..88fc8325aa01 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Slika v sliki"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program brez naslova)"</string> - <string name="pip_close" msgid="9135220303720555525">"Zapri način PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Zapri"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Celozaslonsko"</string> - <string name="pip_move" msgid="1544227837964635439">"Premakni sliko v sliki"</string> - <string name="pip_expand" msgid="7605396312689038178">"Razširi sliko v sliki"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Strni sliko v sliki"</string> + <string name="pip_move" msgid="158770205886688553">"Premakni"</string> + <string name="pip_expand" msgid="1051966011679297308">"Razširi"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Strni"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Za kontrolnike dvakrat pritisnite gumb za "<annotation icon="home_icon">" ZAČETNI ZASLON "</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meni za sliko v sliki"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Premakni levo"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Premakni desno"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Premakni navzgor"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Premakni navzdol"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Končano"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index 2839b4bae7e4..6e26ec6214ef 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Cilësimet"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Hyr në ekranin e ndarë"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyja"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menyja e \"Figurës brenda figurës\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> është në figurë brenda figurës"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Nëse nuk dëshiron që <xliff:g id="NAME">%s</xliff:g> ta përdorë këtë funksion, trokit për të hapur cilësimet dhe për ta çaktivizuar."</string> <string name="pip_play" msgid="3496151081459417097">"Luaj"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ndarësi i ekranit të ndarë"</string> + <string name="divider_title" msgid="5482989479865361192">"Ndarësi i ekranit të ndarë"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Ekrani i plotë majtas"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Majtas 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Majtas 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Trokit për të rifilluar këtë aplikacion për një pamje më të mirë."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Ka probleme me kamerën?\nTrokit për ta ripërshtatur"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Disa aplikacione funksionojnë më mirë në modalitetin vertikal"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Provo një nga këto opsione për ta shfrytëzuar sa më mirë hapësirën"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rrotullo ekranin për të kaluar në ekran të plotë"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Trokit dy herë pranë një aplikacioni për ta ripozicionuar"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Shiko dhe bëj më shumë"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Zvarrite në një aplikacion tjetër për ekranin e ndarë"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Trokit dy herë jashtë një aplikacioni për ta ripozicionuar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"E kuptova"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Zgjeroje për më shumë informacion."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizo"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimizo"</string> + <string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml index 9bfdb6a3edd8..58687e5867fe 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Figurë brenda figurës"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program pa titull)"</string> - <string name="pip_close" msgid="9135220303720555525">"Mbyll PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Mbyll"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Ekrani i plotë"</string> - <string name="pip_move" msgid="1544227837964635439">"Zhvendos PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Zgjero PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Palos PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Lëviz"</string> + <string name="pip_expand" msgid="1051966011679297308">"Zgjero"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Palos"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Trokit dy herë "<annotation icon="home_icon">" KREU "</annotation>" për kontrollet"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menyja e \"Figurës brenda figurës\"."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Lëviz majtas"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Lëviz djathtas"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Lëviz lart"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Lëviz poshtë"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"U krye"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 9db6b7c63610..94725cbdf367 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Подешавања"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Уђи на подељени екран"</string> <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_play" msgid="3496151081459417097">"Пусти"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Разделник подељеног екрана"</string> + <string name="divider_title" msgid="5482989479865361192">"Разделник подељеног екрана"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Неке апликације најбоље функционишу у усправном режиму"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Испробајте једну од ових опција да бисте на најбољи начин искористили простор"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ротирајте уређај за приказ преко целог екрана"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Двапут додирните поред апликације да бисте променили њену позицију"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Видите и урадите више"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Превуците другу апликацију да бисте користили подељени екран"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"Увећајте"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Умањите"</string> + <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml index 6bc5c87bab48..e850979174a3 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Слика у слици"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програм без наслова)"</string> - <string name="pip_close" msgid="9135220303720555525">"Затвори PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Затвори"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Цео екран"</string> - <string name="pip_move" msgid="1544227837964635439">"Премести слику у слици"</string> - <string name="pip_expand" msgid="7605396312689038178">"Прошири слику у слици"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Скупи слику у слици"</string> + <string name="pip_move" msgid="158770205886688553">"Премести"</string> + <string name="pip_expand" msgid="1051966011679297308">"Прошири"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Скупи"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Двапут притисните "<annotation icon="home_icon">" HOME "</annotation>" за контроле"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Мени Слика у слици."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Померите налево"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Померите надесно"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Померите нагоре"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Померите надоле"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index f6bd55423cdc..6b6ba2b2d298 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Inställningar"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Starta delad skärm"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Bild-i-bild-meny"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> visas i bild-i-bild"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Om du inte vill att den här funktionen används i <xliff:g id="NAME">%s</xliff:g> öppnar du inställningarna genom att trycka. Sedan inaktiverar du funktionen."</string> <string name="pip_play" msgid="3496151081459417097">"Spela upp"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen kanske inte fungerar på en sekundär skärm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan inte köras på en sekundär skärm."</string> <string name="accessibility_divider" msgid="703810061635792791">"Avdelare för delad skärm"</string> + <string name="divider_title" msgid="5482989479865361192">"Avdelare för delad skärm"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Helskärm på vänster skärm"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Vänster 70 %"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vänster 50 %"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Tryck för att starta om appen i helskärmsläge."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Tryck för att starta om appen och få en bättre vy."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problem med kameran?\nTryck för att anpassa på nytt"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Vissa appar fungerar bäst i stående läge"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Testa med ett av dessa alternativ för att få ut mest möjliga av ytan"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotera skärmen för att gå över till helskärmsläge"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tryck snabbt två gånger bredvid en app för att flytta den"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se och gör mer"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Dra till en annan app för läget Delad skärm"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryck snabbt två gånger utanför en app för att flytta den"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Utöka för mer information."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Utöka"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Minimera"</string> + <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sv/strings_tv.xml b/libs/WindowManager/Shell/res/values-sv/strings_tv.xml index b3465ab1db85..d3a9c3de66db 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Bild-i-bild"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Namnlöst program)"</string> - <string name="pip_close" msgid="9135220303720555525">"Stäng PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Stäng"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Helskärm"</string> - <string name="pip_move" msgid="1544227837964635439">"Flytta BIB"</string> - <string name="pip_expand" msgid="7605396312689038178">"Utöka bild-i-bild"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Komprimera bild-i-bild"</string> + <string name="pip_move" msgid="158770205886688553">"Flytta"</string> + <string name="pip_expand" msgid="1051966011679297308">"Utöka"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Komprimera"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Tryck snabbt två gånger på "<annotation icon="home_icon">" HEM "</annotation>" för kontroller"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Bild-i-bild-meny."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Flytta åt vänster"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Flytta åt höger"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Flytta uppåt"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Flytta nedåt"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Klar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index f6e558527ee5..102e9cfae2e4 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Mipangilio"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Weka skrini iliyogawanywa"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menyu ya kipengele cha Kupachika Picha ndani ya Picha nyingine."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> iko katika hali ya picha ndani ya picha nyingine"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Ikiwa hutaki <xliff:g id="NAME">%s</xliff:g> itumie kipengele hiki, gusa ili ufungue mipangilio na uizime."</string> <string name="pip_play" msgid="3496151081459417097">"Cheza"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Huenda programu isifanye kazi kwenye dirisha lingine."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string> <string name="accessibility_divider" msgid="703810061635792791">"Kitenganishi cha skrini inayogawanywa"</string> + <string name="divider_title" msgid="5482989479865361192">"Kitenganishi cha kugawa skrini"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Skrini nzima ya kushoto"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kushoto 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kushoto 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Gusa ili uzime na uwashe programu hii, kisha nenda kwenye skrini nzima."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Gusa ili uzime kisha uwashe programu hii, ili upate mwonekano bora."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Je, kuna hitilafu za kamera?\nGusa ili urekebishe"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Baadhi ya programu hufanya kazi vizuri zaidi zikiwa wima"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Jaribu moja kati ya chaguo hizi ili utumie nafasi ya skrini yako kwa ufanisi"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zungusha kifaa chako ili uende kwenye hali ya skrini nzima"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Gusa mara mbili karibu na programu ili uihamishe"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Angalia na ufanye zaidi"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Buruta ndani programu nyingine ili utumie hali ya skrini iliyogawanywa"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Gusa mara mbili nje ya programu ili uihamishe"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Nimeelewa"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Panua ili upate maelezo zaidi."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Panua"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Punguza"</string> + <string name="close_button_text" msgid="2913281996024033299">"Funga"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sw/strings_tv.xml b/libs/WindowManager/Shell/res/values-sw/strings_tv.xml index baff49ed821a..7b9a310ff0b6 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pachika Picha Ndani ya Picha Nyingine"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programu isiyo na jina)"</string> - <string name="pip_close" msgid="9135220303720555525">"Funga PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Funga"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Skrini nzima"</string> - <string name="pip_move" msgid="1544227837964635439">"Kuhamisha PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Panua PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Kunja PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Hamisha"</string> + <string name="pip_expand" msgid="1051966011679297308">"Panua"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Kunja"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Bonyeza mara mbili kitufe cha "<annotation icon="home_icon">" UKURASA WA KWANZA "</annotation>" kupata vidhibiti"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menyu ya kipengele cha kupachika picha ndani ya picha nyingine."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Sogeza kushoto"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Sogeza kulia"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Sogeza juu"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Sogeza chini"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Imemaliza"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index d8334adfe5ef..c2166fdb136a 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"அமைப்புகள்"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"திரைப் பிரிப்பு பயன்முறைக்குச் செல்"</string> <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_play" msgid="3496151081459417097">"இயக்கு"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"திரையைப் பிரிக்கும் பிரிப்பான்"</string> + <string name="divider_title" msgid="5482989479865361192">"திரைப் பிரிப்பான்"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"சில ஆப்ஸ் \'போர்ட்ரெய்ட்டில்\' சிறப்பாகச் செயல்படும்"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ஸ்பேஸ்களிலிருந்து அதிகப் பலன்களைப் பெற இந்த விருப்பங்களில் ஒன்றைப் பயன்படுத்துங்கள்"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"முழுத்திரைக்குச் செல்ல உங்கள் சாதனத்தைச் சுழற்றவும்"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ஆப்ஸை இடம் மாற்ற, ஆப்ஸுக்கு அடுத்து இருமுறை தட்டவும்"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"பலவற்றைப் பார்த்தல் மற்றும் செய்தல்"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"திரைப் பிரிப்புக்கு மற்றொரு ஆப்ஸை இழுக்கலாம்"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"பெரிதாக்கும்"</string> + <string name="minimize_button_text" msgid="271592547935841753">"சிறிதாக்கும்"</string> + <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ta/strings_tv.xml b/libs/WindowManager/Shell/res/values-ta/strings_tv.xml index 4439e299c919..e201401e2e35 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"பிக்ச்சர்-இன்-பிக்ச்சர்"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(தலைப்பு இல்லை)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIPஐ மூடு"</string> + <string name="pip_close" msgid="2955969519031223530">"மூடுக"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"முழுத்திரை"</string> - <string name="pip_move" msgid="1544227837964635439">"PIPபை நகர்த்து"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIPபை விரிவாக்கு"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIPபைச் சுருக்கு"</string> + <string name="pip_move" msgid="158770205886688553">"நகர்த்து"</string> + <string name="pip_expand" msgid="1051966011679297308">"விரி"</string> + <string name="pip_collapse" msgid="3903295106641385962">"சுருக்கு"</string> <string name="pip_edu_text" msgid="3672999496647508701">" கட்டுப்பாடுகள்: "<annotation icon="home_icon">" முகப்பு "</annotation>" பட்டனை இருமுறை அழுத்துக"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"பிக்ச்சர்-இன்-பிக்ச்சர் மெனு."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"இடப்புறம் நகர்த்து"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"வலப்புறம் நகர்த்து"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"மேலே நகர்த்து"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"கீழே நகர்த்து"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"முடிந்தது"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 733075550007..ef0f9e7a6cff 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"సెట్టింగ్లు"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"స్ప్లిట్ స్క్రీన్ను ఎంటర్ చేయండి"</string> <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_play" msgid="3496151081459417097">"ప్లే చేయి"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"విభజన స్క్రీన్ విభాగిని"</string> + <string name="divider_title" msgid="5482989479865361192">"స్ప్లిట్ స్క్రీన్ డివైడర్"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"ఈ యాప్ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేసి, ఆపై పూర్తి స్క్రీన్లోకి వెళ్లండి."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"కొన్ని యాప్లు పోర్ట్రెయిట్లో ఉత్తమంగా పని చేస్తాయి"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"మీ ప్రదేశాన్ని ఎక్కువగా ఉపయోగించుకోవడానికి ఈ ఆప్షన్లలో ఒకదాన్ని ట్రై చేయండి"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ఫుల్ స్క్రీన్కు వెళ్లడానికి మీ పరికరాన్ని తిప్పండి"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"యాప్ స్థానాన్ని మార్చడానికి దాని పక్కన డబుల్-ట్యాప్ చేయండి"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"చూసి, మరిన్ని చేయండి"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"స్ప్లిట్-స్క్రీన్ కోసం మరొక యాప్లోకి లాగండి"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"గరిష్టీకరించండి"</string> + <string name="minimize_button_text" msgid="271592547935841753">"కుదించండి"</string> + <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-te/strings_tv.xml b/libs/WindowManager/Shell/res/values-te/strings_tv.xml index 35579346615f..6284d90cb11f 100644 --- a/libs/WindowManager/Shell/res/values-te/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-te/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"పిక్చర్-ఇన్-పిక్చర్"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(శీర్షిక లేని ప్రోగ్రామ్)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIPని మూసివేయి"</string> + <string name="pip_close" msgid="2955969519031223530">"మూసివేయండి"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"ఫుల్-స్క్రీన్"</string> - <string name="pip_move" msgid="1544227837964635439">"PIPను తరలించండి"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIPని విస్తరించండి"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIPని కుదించండి"</string> + <string name="pip_move" msgid="158770205886688553">"తరలించండి"</string> + <string name="pip_expand" msgid="1051966011679297308">"విస్తరించండి"</string> + <string name="pip_collapse" msgid="3903295106641385962">"కుదించండి"</string> <string name="pip_edu_text" msgid="3672999496647508701">" కంట్రోల్స్ కోసం "<annotation icon="home_icon">" HOME "</annotation>" బటన్ రెండుసార్లు నొక్కండి"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"పిక్చర్-ఇన్-పిక్చర్ మెనూ."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ఎడమ వైపుగా జరపండి"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"కుడి వైపుగా జరపండి"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"పైకి జరపండి"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"కిందికి జరపండి"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"పూర్తయింది"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-television/dimen.xml b/libs/WindowManager/Shell/res/values-television/dimen.xml index 14e89f8b08df..376cc4faca6f 100644 --- a/libs/WindowManager/Shell/res/values-television/dimen.xml +++ b/libs/WindowManager/Shell/res/values-television/dimen.xml @@ -21,4 +21,7 @@ <!-- Padding between PIP and keep clear areas that caused it to move. --> <dimen name="pip_keep_clear_area_padding">16dp</dimen> + + <!-- The corner radius for PiP window. --> + <dimen name="pip_corner_radius">0dp</dimen> </resources> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index cfee8ea3242e..7a7575d53035 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"การตั้งค่า"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"เข้าสู่โหมดแบ่งหน้าจอ"</string> <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_play" msgid="3496151081459417097">"เล่น"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"เส้นแบ่งหน้าจอ"</string> + <string name="divider_title" msgid="5482989479865361192">"เส้นแยกหน้าจอ"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"บางแอปทำงานได้ดีที่สุดในแนวตั้ง"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ลองใช้หนึ่งในตัวเลือกเหล่านี้เพื่อให้ได้ประโยชน์สูงสุดจากพื้นที่ว่าง"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"หมุนอุปกรณ์ให้แสดงเต็มหน้าจอ"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"แตะสองครั้งข้างแอปเพื่อเปลี่ยนตำแหน่ง"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"รับชมและทำสิ่งต่างๆ ได้มากขึ้น"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"ลากไปไว้ในแอปอื่นเพื่อแยกหน้าจอ"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"ขยายใหญ่สุด"</string> + <string name="minimize_button_text" msgid="271592547935841753">"ย่อ"</string> + <string name="close_button_text" msgid="2913281996024033299">"ปิด"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-th/strings_tv.xml b/libs/WindowManager/Shell/res/values-th/strings_tv.xml index 0a07d157ec6f..27cf56c6e154 100644 --- a/libs/WindowManager/Shell/res/values-th/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-th/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"การแสดงภาพซ้อนภาพ"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ไม่มีชื่อรายการ)"</string> - <string name="pip_close" msgid="9135220303720555525">"ปิด PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"ปิด"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"เต็มหน้าจอ"</string> - <string name="pip_move" msgid="1544227837964635439">"ย้าย PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"ขยาย PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"ยุบ PIP"</string> + <string name="pip_move" msgid="158770205886688553">"ย้าย"</string> + <string name="pip_expand" msgid="1051966011679297308">"ขยาย"</string> + <string name="pip_collapse" msgid="3903295106641385962">"ยุบ"</string> <string name="pip_edu_text" msgid="3672999496647508701">" กดปุ่ม "<annotation icon="home_icon">" หน้าแรก "</annotation>" สองครั้งเพื่อเปิดการควบคุม"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"เมนูการแสดงภาพซ้อนภาพ"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"ย้ายไปทางซ้าย"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"ย้ายไปทางขวา"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"ย้ายขึ้น"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"ย้ายลง"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"เสร็จ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index eed624dd5069..1c8d94f24dfa 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Mga Setting"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Pumasok sa split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu ng Picture-in-Picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Nasa picture-in-picture ang <xliff:g id="NAME">%s</xliff:g>"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Kung ayaw mong magamit ni <xliff:g id="NAME">%s</xliff:g> ang feature na ito, i-tap upang buksan ang mga setting at i-off ito."</string> <string name="pip_play" msgid="3496151081459417097">"I-play"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Maaaring hindi gumana ang app sa pangalawang display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string> <string name="accessibility_divider" msgid="703810061635792791">"Divider ng split-screen"</string> + <string name="divider_title" msgid="5482989479865361192">"Divider ng split-screen"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"I-full screen ang nasa kaliwa"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Gawing 70% ang nasa kaliwa"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Gawing 50% ang nasa kaliwa"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string> - <string name="restart_button_description" msgid="5887656107651190519">"I-tap para i-restart ang app na ito at mag-full screen."</string> + <string name="restart_button_description" msgid="6712141648865547958">"I-tap para i-restart ang app na ito para sa mas magandang view."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"May mga isyu sa camera?\nI-tap para i-refit"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"May ilang app na pinakamainam gamitin nang naka-portrait"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Subukan ang isa sa mga opsyong ito para masulit ang iyong space"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"I-rotate ang iyong device para mag-full screen"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Mag-double tap sa tabi ng isang app para iposisyon ito ulit"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Tumingin at gumawa ng higit pa"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Mag-drag ng ibang app para sa split screen"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Mag-double tap sa labas ng app para baguhin ang posisyon nito"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"I-expand para sa higit pang impormasyon."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"I-maximize"</string> + <string name="minimize_button_text" msgid="271592547935841753">"I-minimize"</string> + <string name="close_button_text" msgid="2913281996024033299">"Isara"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tl/strings_tv.xml b/libs/WindowManager/Shell/res/values-tl/strings_tv.xml index 9a11a38fa492..4cc050bebe5b 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-Picture"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Walang pamagat na programa)"</string> - <string name="pip_close" msgid="9135220303720555525">"Isara ang PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Isara"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string> - <string name="pip_move" msgid="1544227837964635439">"Ilipat ang PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"I-expand ang PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"I-collapse ang PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Ilipat"</string> + <string name="pip_expand" msgid="1051966011679297308">"I-expand"</string> + <string name="pip_collapse" msgid="3903295106641385962">"I-collapse"</string> <string name="pip_edu_text" msgid="3672999496647508701">" I-double press ang "<annotation icon="home_icon">" HOME "</annotation>" para sa mga kontrol"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menu ng Picture-in-Picture."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Ilipat pakaliwa"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Ilipat pakanan"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Itaas"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Ibaba"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Tapos na"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 2b4a2d0550f0..82e3f5847df8 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana geç"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Pencere içinde pencere menüsü"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>, pencere içinde pencere özelliğini kullanıyor"</string> <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> uygulamasının bu özelliği kullanmasını istemiyorsanız dokunarak ayarları açın ve söz konusu özelliği kapatın."</string> <string name="pip_play" msgid="3496151081459417097">"Oynat"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uygulama ikincil ekranda çalışmayabilir."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bölünmüş ekran ayırıcı"</string> + <string name="divider_title" msgid="5482989479865361192">"Bölünmüş ekran ayırıcı"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Solda tam ekran"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Solda %70"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Solda %50"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Bu uygulamayı yeniden başlatarak daha iyi bir görünüm elde etmek için dokunun."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kameranızda sorun mu var?\nDüzeltmek için dokunun"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Bazı uygulamalar dikey modda en iyi performansı gösterir"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Alanınızı en verimli şekilde kullanmak için bu seçeneklerden birini deneyin"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Tam ekrana geçmek için cihazınızı döndürün"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Yeniden konumlandırmak için uygulamanın yanına iki kez dokunun"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Daha fazlasını görün ve yapın"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Bölünmüş ekran için başka bir uygulamayı sürükleyin"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Yeniden konumlandırmak için uygulamanın dışına iki kez dokunun"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Daha fazla bilgi için genişletin."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Ekranı Kapla"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Küçült"</string> + <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml index bf4bc6f1fff7..69bb608061e4 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pencere İçinde Pencere"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Başlıksız program)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP\'yi kapat"</string> + <string name="pip_close" msgid="2955969519031223530">"Kapat"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Tam ekran"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP\'yi taşı"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP penceresini genişlet"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP penceresini daralt"</string> - <string name="pip_edu_text" msgid="3672999496647508701">" Kontroller için "<annotation icon="home_icon">" ANA SAYFA "</annotation>"\'ya iki kez basın"</string> + <string name="pip_move" msgid="158770205886688553">"Taşı"</string> + <string name="pip_expand" msgid="1051966011679297308">"Genişlet"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Daralt"</string> + <string name="pip_edu_text" msgid="3672999496647508701">" Kontroller için "<annotation icon="home_icon">" ANA SAYFA "</annotation>" düğmesine iki kez basın"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Pencere içinde pencere menüsü."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Sola taşı"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Sağa taşı"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Yukarı taşı"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Aşağı taşı"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Bitti"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml b/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml index 02e726fbc3bf..b45b9ec0c457 100644 --- a/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml +++ b/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml @@ -15,20 +15,20 @@ limitations under the License. --> <resources> - <!-- The dimensions to user for picture-in-picture action buttons. --> - <dimen name="pip_menu_button_size">48dp</dimen> - <dimen name="pip_menu_button_radius">20dp</dimen> - <dimen name="pip_menu_icon_size">20dp</dimen> - <dimen name="pip_menu_button_margin">4dp</dimen> - <dimen name="pip_menu_button_wrapper_margin">26dp</dimen> - <dimen name="pip_menu_border_width">4dp</dimen> - <integer name="pip_menu_fade_animation_duration">500</integer> + <!-- The dimensions to use for tv window menu action buttons. --> + <dimen name="tv_window_menu_button_size">48dp</dimen> + <dimen name="tv_window_menu_button_radius">20dp</dimen> + <dimen name="tv_window_menu_icon_size">20dp</dimen> + <dimen name="tv_window_menu_button_margin">4dp</dimen> + <integer name="tv_window_menu_fade_animation_duration">500</integer> <!-- The pip menu front border corner radius is 2dp smaller than the background corner radius to hide the background from showing through. --> <dimen name="pip_menu_border_corner_radius">4dp</dimen> <dimen name="pip_menu_background_corner_radius">6dp</dimen> + <dimen name="pip_menu_border_width">4dp</dimen> <dimen name="pip_menu_outer_space">24dp</dimen> + <dimen name="pip_menu_button_wrapper_margin">26dp</dimen> <!-- outer space minus border width --> <dimen name="pip_menu_outer_space_frame">20dp</dimen> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index c3411a837c78..218d11eaba0a 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Налаштування"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Розділити екран"</string> <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_play" msgid="3496151081459417097">"Відтворити"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"Розділювач екрана"</string> + <string name="divider_title" msgid="5482989479865361192">"Розділювач екрана"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Деякі додатки найкраще працюють у вертикальній орієнтації"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Щоб максимально ефективно використовувати місце на екрані, спробуйте виконати одну з наведених нижче дій"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Щоб перейти в повноекранний режим, поверніть пристрій"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Щоб перемістити додаток, двічі торкніться області поруч із ним"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Більше простору та можливостей"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Щоб перейти в режим розділення екрана, перетягніть сюди інший додаток"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Щоб перемістити додаток, двічі торкніться області поза ним"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Розгорніть, щоб дізнатися більше."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Збільшити"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Згорнути"</string> + <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml index 7e9f54e68f54..81a8285c58cf 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Картинка в картинці"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Програма без назви)"</string> - <string name="pip_close" msgid="9135220303720555525">"Закрити PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Закрити"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"На весь екран"</string> - <string name="pip_move" msgid="1544227837964635439">"Перемістити картинку в картинці"</string> - <string name="pip_expand" msgid="7605396312689038178">"Розгорнути картинку в картинці"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Згорнути картинку в картинці"</string> + <string name="pip_move" msgid="158770205886688553">"Перемістити"</string> + <string name="pip_expand" msgid="1051966011679297308">"Розгорнути"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Згорнути"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Відкрити елементи керування: двічі натисніть "<annotation icon="home_icon">"HOME"</annotation></string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Меню \"картинка в картинці\""</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Перемістити ліворуч"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Перемістити праворуч"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Перемістити вгору"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Перемістити вниз"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Готово"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index a31c2be25643..4a9c079fc7d1 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"ترتیبات"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"اسپلٹ اسکرین تک رسائی"</string> <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_play" msgid="3496151081459417097">"چلائیں"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"سپلٹ اسکرین تقسیم کار"</string> + <string name="divider_title" msgid="5482989479865361192">"اسپلٹ اسکرین ڈیوائیڈر"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"کچھ ایپس پورٹریٹ میں بہترین کام کرتی ہیں"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"اپنی اسپیس کا زیادہ سے زیادہ فائدہ اٹھانے کے لیے ان اختیارات میں سے ایک کو آزمائیں"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"پوری اسکرین پر جانے کیلئے اپنا آلہ گھمائیں"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"کسی ایپ کی پوزیشن تبدیل کرنے کے لیے اس کے آگے دو بار تھپتھپائیں"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"دیکھیں اور بہت کچھ کریں"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"اسپلٹ اسکرین کے ليے دوسری ایپ میں گھسیٹیں"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"بڑا کریں"</string> + <string name="minimize_button_text" msgid="271592547935841753">"چھوٹا کریں"</string> + <string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ur/strings_tv.xml b/libs/WindowManager/Shell/res/values-ur/strings_tv.xml index c2ef69ff1488..e83885772f2d 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"تصویر میں تصویر"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(بلا عنوان پروگرام)"</string> - <string name="pip_close" msgid="9135220303720555525">"PIP بند کریں"</string> + <string name="pip_close" msgid="2955969519031223530">"بند کریں"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"فُل اسکرین"</string> - <string name="pip_move" msgid="1544227837964635439">"PIP کو منتقل کریں"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP کو پھیلائیں"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP کو سکیڑیں"</string> + <string name="pip_move" msgid="158770205886688553">"منتقل کریں"</string> + <string name="pip_expand" msgid="1051966011679297308">"پھیلائیں"</string> + <string name="pip_collapse" msgid="3903295106641385962">"سکیڑیں"</string> <string name="pip_edu_text" msgid="3672999496647508701">" کنٹرولز کے لیے "<annotation icon="home_icon">"ہوم "</annotation>" بٹن کو دو بار دبائیں"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"تصویر میں تصویر کا مینو۔"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"دائیں منتقل کریں"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"بائیں منتقل کریں"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"اوپر منتقل کریں"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"نیچے منتقل کریں"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"ہو گیا"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 2e3222560dde..a063476e1aa8 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Sozlamalar"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Ajratilgan ekranga kirish"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Tasvir ustida tasvir menyusi"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> tasvir ustida tasvir rejimida"</string> <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ilovasi uchun bu funksiyani sozlamalar orqali faolsizlantirish mumkin."</string> <string name="pip_play" msgid="3496151081459417097">"Ijro"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string> <string name="accessibility_divider" msgid="703810061635792791">"Ekranni ikkiga bo‘lish chizig‘i"</string> + <string name="divider_title" msgid="5482989479865361192">"Ekranni ikkiga ajratish chizigʻi"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Chapda to‘liq ekran"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Chapda 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Chapda 50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Bu ilovani qaytadan ishga tushirish va butun ekranda ochish uchun bosing."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Yaxshiroq koʻrish maqsadida bu ilovani qayta ishga tushirish uchun bosing."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera nosozmi?\nQayta moslash uchun bosing"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Ayrim ilovalar tik holatda ishlashga eng mos"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Muhitdan yanada samarali foydalanish uchun quyidagilardan birini sinang"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Butun ekranda ochish uchun qurilmani buring"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Qayta joylash uchun keyingi ilova ustiga ikki marta bosing"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Yana boshqa amallar"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Ekranni ikkiga ajratish uchun boshqa ilovani bu yerga torting"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Qayta joylash uchun ilova tashqarisiga ikki marta bosing"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Batafsil axborot olish uchun kengaytiring."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Yoyish"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Kichraytirish"</string> + <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uz/strings_tv.xml b/libs/WindowManager/Shell/res/values-uz/strings_tv.xml index 9ab95c80aa25..da953356628c 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Tasvir ustida tasvir"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Nomsiz)"</string> - <string name="pip_close" msgid="9135220303720555525">"Kadr ichida kadr – chiqish"</string> + <string name="pip_close" msgid="2955969519031223530">"Yopish"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Butun ekran"</string> - <string name="pip_move" msgid="1544227837964635439">"PIPni siljitish"</string> - <string name="pip_expand" msgid="7605396312689038178">"PIP funksiyasini yoyish"</string> - <string name="pip_collapse" msgid="5732233773786896094">"PIP funksiyasini yopish"</string> + <string name="pip_move" msgid="158770205886688553">"Boshqa joyga olish"</string> + <string name="pip_expand" msgid="1051966011679297308">"Yoyish"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Yopish"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Boshqaruv uchun "<annotation icon="home_icon">"ASOSIY"</annotation>" tugmani ikki marta bosing"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Tasvir ustida tasvir menyusi."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Chapga olish"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Oʻngga olish"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Tepaga olish"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Pastga olish"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Tayyor"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 8f3cffecc952..b47296590324 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Cài đặt"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Truy cập chế độ chia đôi màn hình"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Trình đơn hình trong hình."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> đang ở chế độ ảnh trong ảnh"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Nếu bạn không muốn <xliff:g id="NAME">%s</xliff:g> sử dụng tính năng này, hãy nhấn để mở cài đặt và tắt tính năng này."</string> <string name="pip_play" msgid="3496151081459417097">"Phát"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string> <string name="accessibility_divider" msgid="703810061635792791">"Bộ chia chia đôi màn hình"</string> + <string name="divider_title" msgid="5482989479865361192">"Bộ chia màn hình"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Toàn màn hình bên trái"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Trái 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Trái 50%"</string> @@ -72,13 +74,16 @@ <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="5887656107651190519">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</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="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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Một số ứng dụng hoạt động tốt nhất ở chế độ dọc"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Hãy thử một trong các tuỳ chọn sau để tận dụng không gian"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Xoay thiết bị để chuyển sang chế độ toàn màn hình"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Nhấn đúp vào bên cạnh ứng dụng để đặt lại vị trí"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Xem và làm được nhiều việc hơn"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Kéo vào một ứng dụng khác để chia đôi màn hình"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Nhấn đúp bên ngoài ứng dụng để đặt lại vị trí"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mở rộng để xem thêm thông tin."</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Phóng to"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Thu nhỏ"</string> + <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-vi/strings_tv.xml b/libs/WindowManager/Shell/res/values-vi/strings_tv.xml index 146376d3cab6..1f9260fdcff0 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Hình trong hình"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Không có chương trình tiêu đề)"</string> - <string name="pip_close" msgid="9135220303720555525">"Đóng PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Đóng"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Toàn màn hình"</string> - <string name="pip_move" msgid="1544227837964635439">"Di chuyển PIP (Ảnh trong ảnh)"</string> - <string name="pip_expand" msgid="7605396312689038178">"Mở rộng PIP (Ảnh trong ảnh)"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Thu gọn PIP (Ảnh trong ảnh)"</string> + <string name="pip_move" msgid="158770205886688553">"Di chuyển"</string> + <string name="pip_expand" msgid="1051966011679297308">"Mở rộng"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Thu gọn"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Nhấn đúp vào nút "<annotation icon="home_icon">" MÀN HÌNH CHÍNH "</annotation>" để mở trình đơn điều khiển"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Trình đơn hình trong hình."</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Di chuyển sang trái"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Di chuyển sang phải"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Di chuyển lên"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Di chuyển xuống"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Xong"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 19a9d371e435..d7366952f155 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"设置"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"进入分屏模式"</string> <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_play" msgid="3496151081459417097">"播放"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"分屏分隔线"</string> + <string name="divider_title" msgid="5482989479865361192">"分屏分隔线"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"点按即可重启此应用并进入全屏模式。"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"某些应用在纵向模式下才能发挥最佳效果"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"这些选项都有助于您最大限度地利用屏幕空间,不妨从中择一试试"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋转设备即可进入全屏模式"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在某个应用旁边连续点按两次,即可调整它的位置"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"查看和处理更多任务"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"拖入另一个应用,即可使用分屏模式"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> + <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> + <string name="close_button_text" msgid="2913281996024033299">"关闭"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml index 55407d2c699d..399d639fe70f 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"画中画"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(节目没有标题)"</string> - <string name="pip_close" msgid="9135220303720555525">"关闭画中画"</string> + <string name="pip_close" msgid="2955969519031223530">"关闭"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"全屏"</string> - <string name="pip_move" msgid="1544227837964635439">"移动画中画窗口"</string> - <string name="pip_expand" msgid="7605396312689038178">"展开 PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"收起 PIP"</string> + <string name="pip_move" msgid="158770205886688553">"移动"</string> + <string name="pip_expand" msgid="1051966011679297308">"展开"</string> + <string name="pip_collapse" msgid="3903295106641385962">"收起"</string> <string name="pip_edu_text" msgid="3672999496647508701">" 按两次"<annotation icon="home_icon">"主屏幕"</annotation>"按钮可查看相关控件"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"画中画菜单。"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"左移"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"右移"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"上移"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"下移"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"完成"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index 0c40e963f2e4..8eda853fbf2b 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割螢幕"</string> <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_play" msgid="3496151081459417097">"播放"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"分割畫面分隔線"</string> + <string name="divider_title" msgid="5482989479865361192">"分割螢幕分隔線"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"輕按即可重新開啟此應用程式並放大至全螢幕。"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"部分應用程式需要使用直向模式才能發揮最佳效果"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"請嘗試以下選項,充分運用螢幕的畫面空間"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋轉裝置方向即可進入全螢幕模式"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在應用程式旁輕按兩下即可調整位置"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"拖入另一個應用程式即可分割螢幕"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> + <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> + <string name="close_button_text" msgid="2913281996024033299">"關閉"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml index 15e278d8ecc2..acbc26d033cd 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"畫中畫"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(沒有標題的節目)"</string> - <string name="pip_close" msgid="9135220303720555525">"關閉 PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"關閉"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"全螢幕"</string> - <string name="pip_move" msgid="1544227837964635439">"移動畫中畫"</string> - <string name="pip_expand" msgid="7605396312689038178">"展開畫中畫"</string> - <string name="pip_collapse" msgid="5732233773786896094">"收合畫中畫"</string> + <string name="pip_move" msgid="158770205886688553">"移動"</string> + <string name="pip_expand" msgid="1051966011679297308">"展開"</string> + <string name="pip_collapse" msgid="3903295106641385962">"收合"</string> <string name="pip_edu_text" msgid="3672999496647508701">" 按兩下"<annotation icon="home_icon">" 主畫面按鈕"</annotation>"即可顯示控制項"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"畫中畫選單。"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"向左移"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"向右移"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"向上移"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"向下移"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"完成"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 8691352cf94a..71f4f2b96346 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割畫面"</string> <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_play" msgid="3496151081459417097">"播放"</string> @@ -36,6 +37,7 @@ <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="703810061635792791">"分割畫面分隔線"</string> + <string name="divider_title" msgid="5482989479865361192">"分割畫面分隔線"</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> @@ -72,13 +74,16 @@ <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="5887656107651190519">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</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> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"某些應用程式在直向模式下才能發揮最佳效果"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"請試試這裡的任一方式,以充分運用螢幕畫面的空間"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋轉裝置方向即可進入全螢幕模式"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在應用程式旁輕觸兩下即可調整位置"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"拖進另一個應用程式即可使用分割畫面模式"</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> + <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> + <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> + <string name="close_button_text" msgid="2913281996024033299">"關閉"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml index 0b17b31d23d0..f8c683ec3a60 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"子母畫面"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(無標題的節目)"</string> - <string name="pip_close" msgid="9135220303720555525">"關閉子母畫面"</string> + <string name="pip_close" msgid="2955969519031223530">"關閉"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"全螢幕"</string> - <string name="pip_move" msgid="1544227837964635439">"移動子母畫面"</string> - <string name="pip_expand" msgid="7605396312689038178">"展開子母畫面"</string> - <string name="pip_collapse" msgid="5732233773786896094">"收合子母畫面"</string> + <string name="pip_move" msgid="158770205886688553">"移動"</string> + <string name="pip_expand" msgid="1051966011679297308">"展開"</string> + <string name="pip_collapse" msgid="3903295106641385962">"收合"</string> <string name="pip_edu_text" msgid="3672999496647508701">" 按兩下"<annotation icon="home_icon">"主畫面按鈕"</annotation>"即可顯示控制選項"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"子母畫面選單。"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"向左移動"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"向右移動"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"向上移動"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"向下移動"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"完成"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 44ffbc6afa45..f637912b8ed9 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -22,6 +22,7 @@ <string name="pip_phone_settings" msgid="5468987116750491918">"Izilungiselelo"</string> <string name="pip_phone_enter_split" msgid="7042877263880641911">"Faka ukuhlukanisa isikrini"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Imenyu"</string> + <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Imenyu Yesithombe-Esithombeni"</string> <string name="pip_notification_title" msgid="1347104727641353453">"U-<xliff:g id="NAME">%s</xliff:g> ungaphakathi kwesithombe esiphakathi kwesithombe"</string> <string name="pip_notification_message" msgid="8854051911700302620">"Uma ungafuni i-<xliff:g id="NAME">%s</xliff:g> ukuthi isebenzise lesi sici, thepha ukuze uvule izilungiselelo uphinde uyivale."</string> <string name="pip_play" msgid="3496151081459417097">"Dlala"</string> @@ -36,6 +37,7 @@ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string> <string name="accessibility_divider" msgid="703810061635792791">"Isihlukanisi sokuhlukanisa isikrini"</string> + <string name="divider_title" msgid="5482989479865361192">"Isihlukanisi sokuhlukanisa isikrini"</string> <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Isikrini esigcwele esingakwesokunxele"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"Kwesokunxele ngo-70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kwesokunxele ngo-50%"</string> @@ -72,13 +74,16 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string> - <string name="restart_button_description" msgid="5887656107651190519">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Thepha ukuze uqale kabusha le app ukuze ibonakale kangcono."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Izinkinga zekhamera?\nThepha ukuze uyilinganise kabusha"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string> - <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Amanye ama-app asebenza ngcono uma eme ngobude"</string> - <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Zama enye yalezi zinketho ukuze usebenzise isikhala sakho ngokugcwele"</string> - <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zungezisa idivayisi yakho ukuze uye esikrinini esigcwele"</string> - <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Thepha kabili eduze kwe-app ukuze uyimise kabusha"</string> + <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Bona futhi wenze okuningi"</string> + <string name="letterbox_education_split_screen_text" msgid="6206339484068670830">"Hudula kwenye i-app mayelana nokuhlukanisa isikrini"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Thepha kabili ngaphandle kwe-app ukuze uyimise kabusha"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ngiyezwa"</string> + <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Nweba ukuze uthole ulwazi olwengeziwe"</string> + <string name="maximize_button_text" msgid="1650859196290301963">"Khulisa"</string> + <string name="minimize_button_text" msgid="271592547935841753">"Nciphisa"</string> + <string name="close_button_text" msgid="2913281996024033299">"Vala"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zu/strings_tv.xml b/libs/WindowManager/Shell/res/values-zu/strings_tv.xml index dad8c8128222..20243a9dfc9c 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings_tv.xml @@ -19,10 +19,16 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Isithombe-esithombeni"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Alukho uhlelo lwesihloko)"</string> - <string name="pip_close" msgid="9135220303720555525">"Vala i-PIP"</string> + <string name="pip_close" msgid="2955969519031223530">"Vala"</string> <string name="pip_fullscreen" msgid="7278047353591302554">"Iskrini esigcwele"</string> - <string name="pip_move" msgid="1544227837964635439">"Hambisa i-PIP"</string> - <string name="pip_expand" msgid="7605396312689038178">"Nweba i-PIP"</string> - <string name="pip_collapse" msgid="5732233773786896094">"Goqa i-PIP"</string> + <string name="pip_move" msgid="158770205886688553">"Hambisa"</string> + <string name="pip_expand" msgid="1051966011679297308">"Nweba"</string> + <string name="pip_collapse" msgid="3903295106641385962">"Goqa"</string> <string name="pip_edu_text" msgid="3672999496647508701">" Chofoza kabili "<annotation icon="home_icon">" IKHAYA"</annotation>" mayelana nezilawuli"</string> + <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Imenyu yesithombe-esithombeni"</string> + <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Yisa kwesokunxele"</string> + <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Yisa kwesokudla"</string> + <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Khuphula"</string> + <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Yehlisa"</string> + <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Kwenziwe"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values/colors_tv.xml b/libs/WindowManager/Shell/res/values/colors_tv.xml index fa90fe36b545..e6933ca3fce6 100644 --- a/libs/WindowManager/Shell/res/values/colors_tv.xml +++ b/libs/WindowManager/Shell/res/values/colors_tv.xml @@ -15,14 +15,17 @@ ~ limitations under the License. --> <resources> - <color name="tv_pip_menu_icon_focused">#0E0E0F</color> - <color name="tv_pip_menu_icon_unfocused">#F8F9FA</color> - <color name="tv_pip_menu_icon_disabled">#80868B</color> - <color name="tv_pip_menu_close_icon_bg_focused">#D93025</color> - <color name="tv_pip_menu_close_icon_bg_unfocused">#D69F261F</color> - <color name="tv_pip_menu_icon_bg_focused">#E8EAED</color> - <color name="tv_pip_menu_icon_bg_unfocused">#990E0E0F</color> + <color name="tv_window_menu_icon_focused">#0E0E0F</color> + <color name="tv_window_menu_icon_unfocused">#F8F9FA</color> + + <color name="tv_window_menu_icon_disabled">#80868B</color> + <color name="tv_window_menu_close_icon_bg_focused">#D93025</color> + <color name="tv_window_menu_close_icon_bg_unfocused">#D69F261F</color> + <color name="tv_window_menu_icon_bg_focused">#E8EAED</color> + <color name="tv_window_menu_icon_bg_unfocused">#990E0E0F</color> + <color name="tv_pip_menu_focus_border">#E8EAED</color> + <color name="tv_pip_menu_dim_layer">#990E0E0F</color> <color name="tv_pip_menu_background">#1E232C</color> <color name="tv_pip_edu_text">#99D2E3FC</color> diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml index 1d1162daf249..b48a508fddb8 100644 --- a/libs/WindowManager/Shell/res/values/strings.xml +++ b/libs/WindowManager/Shell/res/values/strings.xml @@ -30,6 +30,9 @@ <!-- Title of menu shown over picture-in-picture. Used for accessibility. --> <string name="pip_menu_title">Menu</string> + <!-- accessibility Title of menu shown over picture-in-picture [CHAR LIMIT=NONE] --> + <string name="pip_menu_accessibility_title">Picture-in-Picture Menu</string> + <!-- PiP BTW notification title. [CHAR LIMIT=50] --> <string name="pip_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is in picture-in-picture</string> @@ -73,8 +76,10 @@ <!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. --> <string name="activity_launch_on_secondary_display_failed_text">App does not support launch on secondary displays.</string> - <!-- Accessibility label for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] --> + <!-- Accessibility label and window tile for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] --> <string name="accessibility_divider">Split-screen divider</string> + <!-- Accessibility window title for the split-screen divider window [CHAR LIMIT=NONE] --> + <string name="divider_title">Split-screen divider</string> <!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] --> <string name="accessibility_action_divider_left_full">Left full screen</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index 43679364b443..dec1e38914e2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -44,6 +44,7 @@ import android.util.Log; import android.util.SparseArray; import android.view.SurfaceControl; import android.window.ITaskOrganizerController; +import android.window.ScreenCapture; import android.window.StartingWindowInfo; import android.window.StartingWindowRemovalInfo; import android.window.TaskAppearedInfo; @@ -474,7 +475,7 @@ public class ShellTaskOrganizer extends TaskOrganizer implements * Take a screenshot of a task. */ public void screenshotTask(RunningTaskInfo taskInfo, Rect crop, - Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) { + Consumer<ScreenCapture.ScreenshotHardwareBuffer> consumer) { final TaskAppearedInfo info = mTasks.get(taskInfo.taskId); if (info == null) { return; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING b/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING new file mode 100644 index 000000000000..8dd1369ecbb2 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING @@ -0,0 +1,15 @@ +{ + "ironwood-postsubmit": [ + { + "name": "WMShellFlickerTests", + "options": [ + { + "include-annotation": "android.platform.test.annotations.IwTest" + }, + { + "exclude-annotation": "org.junit.Ignore" + } + ] + } + ] +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index 33ecdd88fad3..ebf8c0354c1b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -16,9 +16,6 @@ package com.android.wm.shell.back; -import static android.view.RemoteAnimationTarget.MODE_CLOSING; -import static android.view.RemoteAnimationTarget.MODE_OPENING; - import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW; @@ -30,6 +27,8 @@ import android.app.WindowConfiguration; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; +import android.graphics.Point; +import android.graphics.PointF; import android.hardware.HardwareBuffer; import android.hardware.input.InputManager; import android.net.Uri; @@ -48,11 +47,8 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; -import android.window.BackAnimationAdaptor; import android.window.BackEvent; import android.window.BackNavigationInfo; -import android.window.IBackAnimationRunner; -import android.window.IBackNaviAnimationController; import android.window.IOnBackInvokedCallback; import com.android.internal.annotations.VisibleForTesting; @@ -79,16 +75,24 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont SETTING_VALUE_ON) != SETTING_VALUE_OFF; private static final int PROGRESS_THRESHOLD = SystemProperties .getInt(PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP, -1); - private final AtomicBoolean mEnableAnimations = new AtomicBoolean(false); - // TODO (b/241808055) Find a appropriate time to remove during refactor - private static final boolean USE_TRANSITION = - SystemProperties.getInt("persist.wm.debug.predictive_back_ani_trans", 1) != 0; /** * Max duration to wait for a transition to finish before accepting another gesture start * request. */ private static final long MAX_TRANSITION_DURATION = 2000; + private final AtomicBoolean mEnableAnimations = new AtomicBoolean(false); + + /** + * Location of the initial touch event of the back gesture. + */ + private final PointF mInitTouchLocation = new PointF(); + + /** + * Raw delta between {@link #mInitTouchLocation} and the last touch location. + */ + private final Point mTouchEventDelta = new Point(); + /** True when a back gesture is ongoing */ private boolean mBackGestureStarted = false; @@ -114,17 +118,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private final Runnable mResetTransitionRunnable = () -> { finishAnimation(); mTransitionInProgress = false; + ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Transition didn't finish in %d ms. Resetting...", + MAX_TRANSITION_DURATION); }; - private RemoteAnimationTarget mAnimationTarget; - IBackAnimationRunner mIBackAnimationRunner; - private IBackNaviAnimationController mBackAnimationController; - private BackAnimationAdaptor mBackAnimationAdaptor; - - private boolean mWaitingAnimationStart; - private final TouchTracker mTouchTracker = new TouchTracker(); - private final CachingBackDispatcher mCachingBackDispatcher = new CachingBackDispatcher(); - @VisibleForTesting final IWindowFocusObserver mFocusObserver = new IWindowFocusObserver.Stub() { @Override @@ -143,92 +140,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } }; - /** - * Helper class to record the touch location for gesture start and latest. - */ - private static class TouchTracker { - /** - * Location of the latest touch event - */ - private float mLatestTouchX; - private float mLatestTouchY; - private int mSwipeEdge; - - /** - * Location of the initial touch event of the back gesture. - */ - private float mInitTouchX; - private float mInitTouchY; - - void update(float touchX, float touchY, int swipeEdge) { - mLatestTouchX = touchX; - mLatestTouchY = touchY; - mSwipeEdge = swipeEdge; - } - - void setGestureStartLocation(float touchX, float touchY) { - mInitTouchX = touchX; - mInitTouchY = touchY; - } - - int getDeltaFromGestureStart(float touchX) { - return Math.round(touchX - mInitTouchX); - } - - void reset() { - mInitTouchX = 0; - mInitTouchY = 0; - } - } - - /** - * Cache the temporary callback and trigger result if gesture was finish before received - * BackAnimationRunner#onAnimationStart/cancel, so there can continue play the animation. - */ - private class CachingBackDispatcher { - private IOnBackInvokedCallback mOnBackCallback; - private boolean mTriggerBack; - // Whether we are waiting to receive onAnimationStart - private boolean mWaitingAnimation; - - void startWaitingAnimation() { - mWaitingAnimation = true; - } - - boolean set(IOnBackInvokedCallback callback, boolean triggerBack) { - if (mWaitingAnimation) { - mOnBackCallback = callback; - mTriggerBack = triggerBack; - return true; - } - return false; - } - - boolean consume() { - boolean consumed = false; - if (mWaitingAnimation && mOnBackCallback != null) { - if (mTriggerBack) { - final BackEvent backFinish = new BackEvent( - mTouchTracker.mLatestTouchX, mTouchTracker.mLatestTouchY, 1, - mTouchTracker.mSwipeEdge, mAnimationTarget); - dispatchOnBackProgressed(mBackToLauncherCallback, backFinish); - dispatchOnBackInvoked(mOnBackCallback); - } else { - final BackEvent backFinish = new BackEvent( - mTouchTracker.mLatestTouchX, mTouchTracker.mLatestTouchY, 0, - mTouchTracker.mSwipeEdge, mAnimationTarget); - dispatchOnBackProgressed(mBackToLauncherCallback, backFinish); - dispatchOnBackCancelled(mOnBackCallback); - } - startTransition(); - consumed = true; - } - mOnBackCallback = null; - mWaitingAnimation = false; - return consumed; - } - } - public BackAnimationController( @NonNull ShellInit shellInit, @NonNull @ShellMainThread ShellExecutor shellExecutor, @@ -364,9 +275,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @VisibleForTesting void setBackToLauncherCallback(IOnBackInvokedCallback callback) { mBackToLauncherCallback = callback; - if (USE_TRANSITION) { - createAdaptor(); - } } private void clearBackToLauncherCallback() { @@ -375,18 +283,15 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @VisibleForTesting void onBackToLauncherAnimationFinished() { - final boolean triggerBack = mTriggerBack; - IOnBackInvokedCallback callback = mBackNavigationInfo != null - ? mBackNavigationInfo.getOnBackInvokedCallback() : null; - // Make sure the notification sequence should be controller > client. - finishAnimation(); - if (callback != null) { - if (triggerBack) { + if (mBackNavigationInfo != null) { + IOnBackInvokedCallback callback = mBackNavigationInfo.getOnBackInvokedCallback(); + if (mTriggerBack) { dispatchOnBackInvoked(callback); } else { dispatchOnBackCancelled(callback); } } + finishAnimation(); } /** @@ -398,8 +303,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (mTransitionInProgress) { return; } - - mTouchTracker.update(touchX, touchY, swipeEdge); if (keyAction == MotionEvent.ACTION_DOWN) { if (!mBackGestureStarted) { mShouldStartOnNextMoveEvent = true; @@ -430,13 +333,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont finishAnimation(); } - mTouchTracker.setGestureStartLocation(touchX, touchY); + mInitTouchLocation.set(touchX, touchY); mBackGestureStarted = true; try { boolean requestAnimation = mEnableAnimations.get(); - mBackNavigationInfo = mActivityTaskManager.startBackNavigation(requestAnimation, - mFocusObserver, mBackAnimationAdaptor); + mBackNavigationInfo = + mActivityTaskManager.startBackNavigation(requestAnimation, mFocusObserver); onBackNavigationInfoReceived(mBackNavigationInfo); } catch (RemoteException remoteException) { Log.e(TAG, "Failed to initAnimation", remoteException); @@ -452,7 +355,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } int backType = backNavigationInfo.getType(); IOnBackInvokedCallback targetCallback = null; - final boolean dispatchToLauncher = shouldDispatchToLauncher(backType); if (backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) { HardwareBuffer hardwareBuffer = backNavigationInfo.getScreenshotHardwareBuffer(); if (hardwareBuffer != null) { @@ -460,17 +362,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont backNavigationInfo.getTaskWindowConfiguration()); } mTransaction.apply(); - } else if (dispatchToLauncher) { + } else if (shouldDispatchToLauncher(backType)) { targetCallback = mBackToLauncherCallback; - if (USE_TRANSITION) { - mCachingBackDispatcher.startWaitingAnimation(); - } } else if (backType == BackNavigationInfo.TYPE_CALLBACK) { targetCallback = mBackNavigationInfo.getOnBackInvokedCallback(); } - if (!USE_TRANSITION || !dispatchToLauncher) { - dispatchOnBackStarted(targetCallback); - } + dispatchOnBackStarted(targetCallback); } /** @@ -509,33 +406,24 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (!mBackGestureStarted || mBackNavigationInfo == null) { return; } - int deltaX = mTouchTracker.getDeltaFromGestureStart(touchX); + int deltaX = Math.round(touchX - mInitTouchLocation.x); float progressThreshold = PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold; float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1); - if (USE_TRANSITION) { - if (mBackAnimationController != null && mAnimationTarget != null) { - final BackEvent backEvent = new BackEvent( - touchX, touchY, progress, swipeEdge, mAnimationTarget); - dispatchOnBackProgressed(mBackToLauncherCallback, backEvent); - } - } else { - int backType = mBackNavigationInfo.getType(); - RemoteAnimationTarget animationTarget = - mBackNavigationInfo.getDepartingAnimationTarget(); - - BackEvent backEvent = new BackEvent( - touchX, touchY, progress, swipeEdge, animationTarget); - IOnBackInvokedCallback targetCallback = null; - if (shouldDispatchToLauncher(backType)) { - targetCallback = mBackToLauncherCallback; - } else if (backType == BackNavigationInfo.TYPE_CROSS_TASK - || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) { - // TODO(208427216) Run the actual animation - } else if (backType == BackNavigationInfo.TYPE_CALLBACK) { - targetCallback = mBackNavigationInfo.getOnBackInvokedCallback(); - } - dispatchOnBackProgressed(targetCallback, backEvent); + int backType = mBackNavigationInfo.getType(); + RemoteAnimationTarget animationTarget = mBackNavigationInfo.getDepartingAnimationTarget(); + + BackEvent backEvent = new BackEvent( + touchX, touchY, progress, swipeEdge, animationTarget); + IOnBackInvokedCallback targetCallback = null; + if (shouldDispatchToLauncher(backType)) { + targetCallback = mBackToLauncherCallback; + } else if (backType == BackNavigationInfo.TYPE_CROSS_TASK + || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) { + // TODO(208427216) Run the actual animation + } else if (backType == BackNavigationInfo.TYPE_CALLBACK) { + targetCallback = mBackNavigationInfo.getOnBackInvokedCallback(); } + dispatchOnBackProgressed(targetCallback, backEvent); } private void injectBackKey() { @@ -589,9 +477,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont IOnBackInvokedCallback targetCallback = shouldDispatchToLauncher ? mBackToLauncherCallback : mBackNavigationInfo.getOnBackInvokedCallback(); - if (mCachingBackDispatcher.set(targetCallback, mTriggerBack)) { - return; - } if (shouldDispatchToLauncher) { startTransition(); } @@ -611,8 +496,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont && mBackToLauncherCallback != null && mEnableAnimations.get() && mBackNavigationInfo != null - && ((USE_TRANSITION && mBackNavigationInfo.isPrepareRemoteAnimation()) - || mBackNavigationInfo.getDepartingAnimationTarget() != null); + && mBackNavigationInfo.getDepartingAnimationTarget() != null; } private static void dispatchOnBackStarted(IOnBackInvokedCallback callback) { @@ -677,7 +561,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private void finishAnimation() { ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: finishAnimation()"); - mTouchTracker.reset(); + mTouchEventDelta.set(0, 0); + mInitTouchLocation.set(0, 0); BackNavigationInfo backNavigationInfo = mBackNavigationInfo; boolean triggerBack = mTriggerBack; mBackNavigationInfo = null; @@ -687,33 +572,19 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return; } - if (!USE_TRANSITION) { - RemoteAnimationTarget animationTarget = backNavigationInfo - .getDepartingAnimationTarget(); - if (animationTarget != null) { - if (animationTarget.leash != null && animationTarget.leash.isValid()) { - mTransaction.remove(animationTarget.leash); - } + RemoteAnimationTarget animationTarget = backNavigationInfo.getDepartingAnimationTarget(); + if (animationTarget != null) { + if (animationTarget.leash != null && animationTarget.leash.isValid()) { + mTransaction.remove(animationTarget.leash); } - SurfaceControl screenshotSurface = backNavigationInfo.getScreenshotSurface(); - if (screenshotSurface != null && screenshotSurface.isValid()) { - mTransaction.remove(screenshotSurface); - } - mTransaction.apply(); } + SurfaceControl screenshotSurface = backNavigationInfo.getScreenshotSurface(); + if (screenshotSurface != null && screenshotSurface.isValid()) { + mTransaction.remove(screenshotSurface); + } + mTransaction.apply(); stopTransition(); backNavigationInfo.onBackNavigationFinished(triggerBack); - if (USE_TRANSITION) { - final IBackNaviAnimationController controller = mBackAnimationController; - if (controller != null) { - try { - controller.finish(triggerBack); - } catch (RemoteException r) { - // Oh no! - } - } - mBackAnimationController = null; - } } private void startTransition() { @@ -731,50 +602,4 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mShellExecutor.removeCallbacks(mResetTransitionRunnable); mTransitionInProgress = false; } - - private void createAdaptor() { - mIBackAnimationRunner = new IBackAnimationRunner.Stub() { - @Override - public void onAnimationCancelled() { - // no op for now - } - @Override // Binder interface - public void onAnimationStart(IBackNaviAnimationController controller, int type, - RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps) { - mShellExecutor.execute(() -> { - mBackAnimationController = controller; - for (int i = 0; i < apps.length; i++) { - final RemoteAnimationTarget target = apps[i]; - if (MODE_CLOSING == target.mode) { - mAnimationTarget = target; - } else if (MODE_OPENING == target.mode) { - // TODO Home activity should handle the visibility for itself - // once it finish relayout for orientation change - SurfaceControl.Transaction tx = - new SurfaceControl.Transaction(); - tx.setAlpha(target.leash, 1); - tx.apply(); - } - } - // TODO animation target should be passed at onBackStarted - dispatchOnBackStarted(mBackToLauncherCallback); - // TODO This is Workaround for LauncherBackAnimationController, there will need - // to dispatch onBackProgressed twice(startBack & updateBackProgress) to - // initialize the animation data, for now that would happen when onMove - // called, but there will no expected animation if the down -> up gesture - // happen very fast which ACTION_MOVE only happen once. - final BackEvent backInit = new BackEvent( - mTouchTracker.mLatestTouchX, mTouchTracker.mLatestTouchY, 0, - mTouchTracker.mSwipeEdge, mAnimationTarget); - dispatchOnBackProgressed(mBackToLauncherCallback, backInit); - if (!mCachingBackDispatcher.consume()) { - dispatchOnBackProgressed(mBackToLauncherCallback, backInit); - } - }); - } - }; - mBackAnimationAdaptor = new BackAnimationAdaptor(mIBackAnimationRunner, - BackNavigationInfo.TYPE_RETURN_TO_HOME); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index 5ea370b65407..8121b206c93a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -53,13 +53,13 @@ import android.util.IntProperty; import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; -import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.LinearLayout; +import android.window.ScreenCapture; import androidx.annotation.Nullable; @@ -516,7 +516,7 @@ public class BubbleExpandedView extends LinearLayout { /** Return a GraphicBuffer with the contents of the task view surface. */ @Nullable - SurfaceControl.ScreenshotHardwareBuffer snapshotActivitySurface() { + ScreenCapture.ScreenshotHardwareBuffer snapshotActivitySurface() { if (mIsOverflow) { // For now, just snapshot the view and return it as a hw buffer so that the animation // code for both the tasks and overflow can be the same @@ -525,7 +525,7 @@ public class BubbleExpandedView extends LinearLayout { p.beginRecording(mOverflowView.getWidth(), mOverflowView.getHeight())); p.endRecording(); Bitmap snapshot = Bitmap.createBitmap(p); - return new SurfaceControl.ScreenshotHardwareBuffer( + return new ScreenCapture.ScreenshotHardwareBuffer( snapshot.getHardwareBuffer(), snapshot.getColorSpace(), false /* containsSecureLayers */, @@ -534,7 +534,7 @@ public class BubbleExpandedView extends LinearLayout { if (mTaskView == null || mTaskView.getSurfaceControl() == null) { return null; } - return SurfaceControl.captureLayers( + return ScreenCapture.captureLayers( mTaskView.getSurfaceControl(), new Rect(0, 0, mTaskView.getWidth(), mTaskView.getHeight()), 1 /* scale */); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index be100bb1dd34..2d9c2a9145ab 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -51,7 +51,6 @@ import android.util.Log; import android.view.Choreographer; import android.view.LayoutInflater; import android.view.MotionEvent; -import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; @@ -64,6 +63,7 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import android.window.ScreenCapture; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -244,7 +244,7 @@ public class BubbleStackView extends FrameLayout * Buffer containing a screenshot of the animating-out bubble. This is drawn into the * SurfaceView during animations. */ - private SurfaceControl.ScreenshotHardwareBuffer mAnimatingOutBubbleBuffer; + private ScreenCapture.ScreenshotHardwareBuffer mAnimatingOutBubbleBuffer; private BubbleFlyoutView mFlyout; /** Runnable that fades out the flyout and then sets it to GONE. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java index 2a1bf0ee42ba..fad3dee1f927 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java @@ -19,6 +19,7 @@ package com.android.wm.shell.common; import android.graphics.PixelFormat; import android.graphics.Rect; import android.view.SurfaceControl; +import android.window.ScreenCapture; import java.util.function.Consumer; @@ -35,9 +36,9 @@ public class ScreenshotUtils { * @param consumer Consumer for the captured buffer */ public static void captureLayer(SurfaceControl sc, Rect crop, - Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) { - consumer.accept(SurfaceControl.captureLayers( - new SurfaceControl.LayerCaptureArgs.Builder(sc) + Consumer<ScreenCapture.ScreenshotHardwareBuffer> consumer) { + consumer.accept(ScreenCapture.captureLayers( + new ScreenCapture.LayerCaptureArgs.Builder(sc) .setSourceCrop(crop) .setCaptureSecureLayers(true) .setAllowProtected(true) @@ -45,7 +46,7 @@ public class ScreenshotUtils { } private static class BufferConsumer implements - Consumer<SurfaceControl.ScreenshotHardwareBuffer> { + Consumer<ScreenCapture.ScreenshotHardwareBuffer> { SurfaceControl mScreenshot = null; SurfaceControl.Transaction mTransaction; SurfaceControl mSurfaceControl; @@ -61,7 +62,7 @@ public class ScreenshotUtils { } @Override - public void accept(SurfaceControl.ScreenshotHardwareBuffer buffer) { + public void accept(ScreenCapture.ScreenshotHardwareBuffer buffer) { if (buffer == null || buffer.getHardwareBuffer() == null) { return; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java index a09aab666a31..39b0b5500cea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuActionButton.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.pip.tv; +package com.android.wm.shell.common; import android.content.Context; import android.content.res.TypedArray; @@ -28,33 +28,32 @@ import android.widget.RelativeLayout; import com.android.wm.shell.R; /** - * A View that represents Pip Menu action button, such as "Fullscreen" and "Close" as well custom - * (provided by the application in Pip) and media buttons. + * A common action button for TV window menu layouts. */ -public class TvPipMenuActionButton extends RelativeLayout implements View.OnClickListener { +public class TvWindowMenuActionButton extends RelativeLayout implements View.OnClickListener { private final ImageView mIconImageView; private final View mButtonBackgroundView; private final View mButtonView; private OnClickListener mOnClickListener; - public TvPipMenuActionButton(Context context) { + public TvWindowMenuActionButton(Context context) { this(context, null, 0, 0); } - public TvPipMenuActionButton(Context context, AttributeSet attrs) { + public TvWindowMenuActionButton(Context context, AttributeSet attrs) { this(context, attrs, 0, 0); } - public TvPipMenuActionButton(Context context, AttributeSet attrs, int defStyleAttr) { + public TvWindowMenuActionButton(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } - public TvPipMenuActionButton( + public TvWindowMenuActionButton( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); final LayoutInflater inflater = (LayoutInflater) getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - inflater.inflate(R.layout.tv_pip_menu_action_button, this); + inflater.inflate(R.layout.tv_window_menu_action_button, this); mIconImageView = findViewById(R.id.icon); mButtonView = findViewById(R.id.button); @@ -74,8 +73,8 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic @Override public void setOnClickListener(OnClickListener listener) { - // We do not want to set an OnClickListener to the TvPipMenuActionButton itself, but only to - // the ImageView. So let's "cash" the listener we've been passed here and set a "proxy" + // We do not want to set an OnClickListener to the TvWindowMenuActionButton itself, but only + // to the ImageView. So let's "cash" the listener we've been passed here and set a "proxy" // listener to the ImageView. mOnClickListener = listener; mButtonView.setOnClickListener(listener != null ? this : null); @@ -129,20 +128,27 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic return mButtonView.isEnabled(); } - void setIsCustomCloseAction(boolean isCustomCloseAction) { + /** + * Marks this button as a custom close action button. + * This changes the style of the action button to highlight that this action finishes the + * Picture-in-Picture activity. + * + * @param isCustomCloseAction sets or unsets this button as a custom close action button. + */ + public void setIsCustomCloseAction(boolean isCustomCloseAction) { mIconImageView.setImageTintList( getResources().getColorStateList( - isCustomCloseAction ? R.color.tv_pip_menu_close_icon - : R.color.tv_pip_menu_icon)); + isCustomCloseAction ? R.color.tv_window_menu_close_icon + : R.color.tv_window_menu_icon)); mButtonBackgroundView.setBackgroundTintList(getResources() - .getColorStateList(isCustomCloseAction ? R.color.tv_pip_menu_close_icon_bg - : R.color.tv_pip_menu_icon_bg)); + .getColorStateList(isCustomCloseAction ? R.color.tv_window_menu_close_icon_bg + : R.color.tv_window_menu_icon_bg)); } @Override public String toString() { if (mButtonView.getContentDescription() == null) { - return TvPipMenuActionButton.class.getSimpleName(); + return TvWindowMenuActionButton.class.getSimpleName(); } return mButtonView.getContentDescription().toString(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java index 864b9a7528b0..7fea23797e67 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java @@ -126,6 +126,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { lp.token = new Binder(); lp.setTitle(mWindowName); lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY; + lp.accessibilityTitle = mContext.getResources().getString(R.string.accessibility_divider); mViewHost.setView(mDividerView, lp); mDividerView.setup(splitLayout, this, mViewHost, insetsState); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java index 15bfeb297b41..e9957fd4f4f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java @@ -16,16 +16,32 @@ package com.android.wm.shell.dagger; -import android.view.IWindowManager; +import android.content.Context; +import android.os.Handler; +import com.android.launcher3.icons.IconProvider; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; +import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.SyncTransactionQueue; +import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.annotations.ShellMainThread; +import com.android.wm.shell.draganddrop.DragAndDropController; +import com.android.wm.shell.recents.RecentTasksController; +import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.splitscreen.tv.TvSplitScreenController; import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm; import com.android.wm.shell.startingsurface.tv.TvStartingWindowTypeAlgorithm; +import com.android.wm.shell.sysui.ShellCommandHandler; +import com.android.wm.shell.sysui.ShellController; +import com.android.wm.shell.sysui.ShellInit; +import com.android.wm.shell.transition.Transitions; + +import java.util.Optional; import dagger.Module; import dagger.Provides; @@ -50,5 +66,33 @@ public class TvWMShellModule { @DynamicOverride static StartingWindowTypeAlgorithm provideStartingWindowTypeAlgorithm() { return new TvStartingWindowTypeAlgorithm(); - }; + } + + @WMSingleton + @Provides + @DynamicOverride + static SplitScreenController provideSplitScreenController(Context context, + ShellInit shellInit, + ShellCommandHandler shellCommandHandler, + ShellController shellController, + ShellTaskOrganizer shellTaskOrganizer, + SyncTransactionQueue syncQueue, + RootTaskDisplayAreaOrganizer rootTDAOrganizer, + DisplayController displayController, + DisplayImeController displayImeController, + DisplayInsetsController displayInsetsController, + DragAndDropController dragAndDropController, + Transitions transitions, + TransactionPool transactionPool, + IconProvider iconProvider, + Optional<RecentTasksController> recentTasks, + @ShellMainThread ShellExecutor mainExecutor, + Handler mainHandler, + SystemWindows systemWindows) { + return new TvSplitScreenController(context, shellInit, shellCommandHandler, shellController, + shellTaskOrganizer, syncQueue, rootTDAOrganizer, displayController, + displayImeController, displayInsetsController, dragAndDropController, transitions, + transactionPool, iconProvider, recentTasks, mainExecutor, mainHandler, + systemWindows); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java index 16f1d1c2944c..000624499f79 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java @@ -26,11 +26,14 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import android.annotation.Nullable; import android.app.ActivityManager.RunningTaskInfo; import android.app.RemoteAction; +import android.content.Context; import android.graphics.PixelFormat; import android.graphics.Rect; import android.view.SurfaceControl; import android.view.WindowManager; +import com.android.wm.shell.R; + import java.util.List; /** @@ -97,16 +100,20 @@ public interface PipMenuController { /** * Returns a default LayoutParams for the PIP Menu. + * @param context the context. * @param width the PIP stack width. * @param height the PIP stack height. */ - default WindowManager.LayoutParams getPipMenuLayoutParams(String title, int width, int height) { + default WindowManager.LayoutParams getPipMenuLayoutParams(Context context, String title, + int width, int height) { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height, TYPE_APPLICATION_OVERLAY, FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY | FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT); lp.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY; lp.setTitle(title); + lp.accessibilityTitle = context.getResources().getString( + R.string.pip_menu_accessibility_title); return lp; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java index 281ea530e9e1..a0a8f9fb2cde 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java @@ -186,7 +186,7 @@ public class PhonePipMenuController implements PipMenuController { mPipMenuView = new PipMenuView(mContext, this, mMainExecutor, mMainHandler, mSplitScreenController, mPipUiEventLogger); mSystemWindows.addView(mPipMenuView, - getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */), + getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */), 0, SHELL_ROOT_LAYER_PIP); setShellRootAccessibilityWindow(); @@ -210,7 +210,7 @@ public class PhonePipMenuController implements PipMenuController { @Override public void updateMenuBounds(Rect destinationBounds) { mSystemWindows.updateViewLayout(mPipMenuView, - getPipMenuLayoutParams(MENU_WINDOW_TITLE, destinationBounds.width(), + getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, destinationBounds.width(), destinationBounds.height())); updateMenuLayout(destinationBounds); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS index 85441af9a870..5aa3c4e2abef 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS @@ -1,2 +1,3 @@ # WM shell sub-module TV pip owner galinap@google.com +bronger@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java index ce34d2f9547d..a4b70333850c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java @@ -29,7 +29,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Rect; -import android.util.ArraySet; import android.util.Size; import android.view.Gravity; @@ -50,11 +49,10 @@ import java.util.Set; * Contains pip bounds calculations that are specific to TV. */ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { - private static final String TAG = TvPipBoundsAlgorithm.class.getSimpleName(); - private static final boolean DEBUG = TvPipController.DEBUG; - private final @NonNull TvPipBoundsState mTvPipBoundsState; + @NonNull + private final TvPipBoundsState mTvPipBoundsState; private int mFixedExpandedHeightInPx; private int mFixedExpandedWidthInPx; @@ -92,10 +90,9 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { /** Returns the destination bounds to place the PIP window on entry. */ @Override public Rect getEntryDestinationBounds() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: getEntryDestinationBounds()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: getEntryDestinationBounds()", TAG); + updateExpandedPipSize(); final boolean isPipExpanded = mTvPipBoundsState.isTvExpandedPipSupported() && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0 @@ -110,10 +107,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ @Override public Rect getAdjustedDestinationBounds(Rect currentBounds, float newAspectRatio) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: getAdjustedDestinationBounds: %f", TAG, newAspectRatio); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: getAdjustedDestinationBounds: %f", TAG, newAspectRatio); return adjustBoundsForTemporaryDecor(getTvPipPlacement().getBounds()); } @@ -141,25 +136,9 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { final Rect insetBounds = new Rect(); getInsetBounds(insetBounds); - Set<Rect> restrictedKeepClearAreas = mTvPipBoundsState.getRestrictedKeepClearAreas(); - Set<Rect> unrestrictedKeepClearAreas = mTvPipBoundsState.getUnrestrictedKeepClearAreas(); - - if (mTvPipBoundsState.isImeShowing()) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: IME showing, height: %d", - TAG, mTvPipBoundsState.getImeHeight()); - } - - final Rect imeBounds = new Rect( - 0, - insetBounds.bottom - mTvPipBoundsState.getImeHeight(), - insetBounds.right, - insetBounds.bottom); - - unrestrictedKeepClearAreas = new ArraySet<>(unrestrictedKeepClearAreas); - unrestrictedKeepClearAreas.add(imeBounds); - } + final Set<Rect> restrictedKeepClearAreas = mTvPipBoundsState.getRestrictedKeepClearAreas(); + final Set<Rect> unrestrictedKeepClearAreas = + mTvPipBoundsState.getUnrestrictedKeepClearAreas(); mKeepClearAlgorithm.setGravity(mTvPipBoundsState.getTvPipGravity()); mKeepClearAlgorithm.setScreenSize(screenSize); @@ -173,24 +152,22 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { restrictedKeepClearAreas, unrestrictedKeepClearAreas); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: screenSize: %s", TAG, screenSize); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: stashOffset: %d", TAG, mTvPipBoundsState.getStashOffset()); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: insetBounds: %s", TAG, insetBounds.toShortString()); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: pipSize: %s", TAG, pipSize); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: gravity: %s", TAG, Gravity.toString(mTvPipBoundsState.getTvPipGravity())); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: restrictedKeepClearAreas: %s", TAG, restrictedKeepClearAreas); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: unrestrictedKeepClearAreas: %s", TAG, unrestrictedKeepClearAreas); - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: placement: %s", TAG, placement); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: screenSize: %s", TAG, screenSize); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: stashOffset: %d", TAG, mTvPipBoundsState.getStashOffset()); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: insetBounds: %s", TAG, insetBounds.toShortString()); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: pipSize: %s", TAG, pipSize); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: gravity: %s", TAG, Gravity.toString(mTvPipBoundsState.getTvPipGravity())); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: restrictedKeepClearAreas: %s", TAG, restrictedKeepClearAreas); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: unrestrictedKeepClearAreas: %s", TAG, unrestrictedKeepClearAreas); + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: placement: %s", TAG, placement); return placement; } @@ -199,13 +176,11 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { * @return previous gravity if it is to be saved, or {@link Gravity#NO_GRAVITY} if not. */ int updateGravityOnExpandToggled(int previousGravity, boolean expanding) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: updateGravityOnExpandToggled(), expanding: %b" - + ", mOrientation: %d, previous gravity: %s", - TAG, expanding, mTvPipBoundsState.getTvFixedPipOrientation(), - Gravity.toString(previousGravity)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: updateGravityOnExpandToggled(), expanding: %b" + + ", mOrientation: %d, previous gravity: %s", + TAG, expanding, mTvPipBoundsState.getTvFixedPipOrientation(), + Gravity.toString(previousGravity)); if (!mTvPipBoundsState.isTvExpandedPipSupported()) { return Gravity.NO_GRAVITY; @@ -256,10 +231,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { } } mTvPipBoundsState.setTvPipGravity(updatedGravity); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity)); return gravityToSave; } @@ -268,10 +241,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { * @return true if gravity changed */ boolean updateGravity(int keycode) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: updateGravity, keycode: %d", TAG, keycode); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: updateGravity, keycode: %d", TAG, keycode); // Check if position change is valid if (mTvPipBoundsState.isTvPipExpanded()) { @@ -328,10 +299,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { if (updatedGravity != currentGravity) { mTvPipBoundsState.setTvPipGravity(updatedGravity); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity)); return true; } return false; @@ -362,8 +331,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { final Size expandedSize; if (expandedRatio == 0) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: updateExpandedPipSize(): Expanded mode aspect ratio" - + " of 0 not supported", TAG); + "%s: updateExpandedPipSize(): Expanded mode aspect ratio" + + " of 0 not supported", TAG); return; } else if (expandedRatio < 1) { // vertical @@ -375,16 +344,12 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { float aspectRatioHeight = mFixedExpandedWidthInPx / expandedRatio; if (maxHeight > aspectRatioHeight) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: Accommodate aspect ratio", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Accommodate aspect ratio", TAG); expandedSize = new Size(mFixedExpandedWidthInPx, (int) aspectRatioHeight); } else { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: Aspect ratio is too extreme, use max size", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Aspect ratio is too extreme, use max size", TAG); expandedSize = new Size(mFixedExpandedWidthInPx, maxHeight); } } @@ -397,26 +362,20 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { - pipDecorations.left - pipDecorations.right; float aspectRatioWidth = mFixedExpandedHeightInPx * expandedRatio; if (maxWidth > aspectRatioWidth) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: Accommodate aspect ratio", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Accommodate aspect ratio", TAG); expandedSize = new Size((int) aspectRatioWidth, mFixedExpandedHeightInPx); } else { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: Aspect ratio is too extreme, use max size", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Aspect ratio is too extreme, use max size", TAG); expandedSize = new Size(maxWidth, mFixedExpandedHeightInPx); } } } mTvPipBoundsState.setTvExpandedSize(expandedSize); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: updateExpandedPipSize(): expanded size, width: %d, height: %d", - TAG, expandedSize.getWidth(), expandedSize.getHeight()); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: updateExpandedPipSize(): expanded size, width: %d, height: %d", + TAG, expandedSize.getWidth(), expandedSize.getHeight()); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java index 3a6ce81821ec..b189163a354a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java @@ -39,7 +39,6 @@ import java.util.function.Supplier; * Manages debouncing of PiP movements and scheduling of unstashing. */ public class TvPipBoundsController { - private static final boolean DEBUG = false; private static final String TAG = "TvPipBoundsController"; /** @@ -122,9 +121,9 @@ public class TvPipBoundsController { cancelScheduledPlacement(); applyPlacementBounds(placement.getUnstashedBounds(), animationDuration); } else if (immediate) { + boolean shouldStash = mUnstashRunnable != null || placement.getTriggerStash(); cancelScheduledPlacement(); - applyPlacementBounds(placement.getBounds(), animationDuration); - scheduleUnstashIfNeeded(placement); + applyPlacement(placement, shouldStash, animationDuration); } else { applyPlacementBounds(mCurrentPlacementBounds, animationDuration); schedulePinnedStackPlacement(placement, animationDuration); @@ -133,11 +132,9 @@ public class TvPipBoundsController { private void schedulePinnedStackPlacement(@NonNull final Placement placement, int animationDuration) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: schedulePinnedStackPlacement() - pip bounds: %s", - TAG, placement.getBounds().toShortString()); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: schedulePinnedStackPlacement() - pip bounds: %s", + TAG, placement.getBounds().toShortString()); if (mPendingPlacement != null && Objects.equals(mPendingPlacement.getBounds(), placement.getBounds())) { @@ -171,27 +168,24 @@ public class TvPipBoundsController { } private void applyPendingPlacement() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: applyPendingPlacement()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: applyPendingPlacement()", TAG); if (mPendingPlacement != null) { - if (mPendingStash) { - mPendingStash = false; - scheduleUnstashIfNeeded(mPendingPlacement); - } - - if (mUnstashRunnable != null) { - // currently stashed, use stashed pos - applyPlacementBounds(mPendingPlacement.getBounds(), - mPendingPlacementAnimationDuration); - } else { - applyPlacementBounds(mPendingPlacement.getUnstashedBounds(), - mPendingPlacementAnimationDuration); - } + applyPlacement(mPendingPlacement, mPendingStash, mPendingPlacementAnimationDuration); + mPendingStash = false; + mPendingPlacement = null; } + } - mPendingPlacement = null; + private void applyPlacement(@NonNull final Placement placement, boolean shouldStash, + int animationDuration) { + if (placement.getStashType() != STASH_TYPE_NONE && shouldStash) { + scheduleUnstashIfNeeded(placement); + } + + Rect bounds = + mUnstashRunnable != null ? placement.getBounds() : placement.getUnstashedBounds(); + applyPlacementBounds(bounds, animationDuration); } void onPipDismissed() { @@ -227,10 +221,8 @@ public class TvPipBoundsController { } mPipTargetBounds = bounds; - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: movePipTo() - new pip bounds: %s", TAG, bounds.toShortString()); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: movePipTo() - new pip bounds: %s", TAG, bounds.toShortString()); if (mListener != null) { mListener.onPipTargetBoundsChange(bounds, animationDuration); 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 ca22882187d8..1651f8993dc1 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 @@ -87,6 +87,7 @@ public class TvPipBoundsState extends PipBoundsState { public void resetTvPipState() { mTvFixedPipOrientation = ORIENTATION_UNDETERMINED; mTvPipGravity = DEFAULT_TV_GRAVITY; + mTvPipManuallyCollapsed = false; } /** Set the tv expanded bounds of PiP */ 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 4e1b0469eb96..85a544b2e8de 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 @@ -70,7 +70,6 @@ public class TvPipController implements PipTransitionController.PipTransitionCal TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener, ConfigurationChangeListener, UserChangeListener { private static final String TAG = "TvPipController"; - static final boolean DEBUG = false; private static final int NONEXISTENT_TASK_ID = -1; @@ -80,7 +79,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal STATE_PIP, STATE_PIP_MENU, }) - public @interface State {} + public @interface State { + } /** * State when there is no applications in Pip. @@ -117,7 +117,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal private final ShellExecutor mMainExecutor; private final TvPipImpl mImpl = new TvPipImpl(); - private @State int mState = STATE_NO_PIP; + @State + private int mState = STATE_NO_PIP; private int mPreviousGravity = TvPipBoundsState.DEFAULT_TV_GRAVITY; private int mPinnedTaskId = NONEXISTENT_TASK_ID; @@ -236,16 +237,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void onConfigurationChanged(Configuration newConfig) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onConfigurationChanged(), state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onConfigurationChanged(), state=%s", TAG, stateToName(mState)); if (isPipShown()) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: > closing Pip.", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: > closing Pip.", TAG); closePip(); } @@ -268,16 +265,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal */ @Override public void showPictureInPictureMenu() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: showPictureInPictureMenu(), state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: showPictureInPictureMenu(), state=%s", TAG, stateToName(mState)); if (mState == STATE_NO_PIP) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: > cannot open Menu from the current state.", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: > cannot open Menu from the current state.", TAG); return; } @@ -288,10 +281,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void onMenuClosed() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: closeMenu(), state before=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: closeMenu(), state before=%s", TAG, stateToName(mState)); setState(STATE_PIP); updatePinnedStackBounds(); } @@ -306,10 +297,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal */ @Override public void movePipToFullscreen() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: movePipToFullscreen(), state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: movePipToFullscreen(), state=%s", TAG, stateToName(mState)); mPipTaskOrganizer.exitPip(mResizeAnimationDuration, false /* requestEnterSplit */); onPipDisappeared(); @@ -317,10 +306,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void togglePipExpansion() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: togglePipExpansion()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: togglePipExpansion()", TAG); boolean expanding = !mTvPipBoundsState.isTvPipExpanded(); int saveGravity = mTvPipBoundsAlgorithm .updateGravityOnExpandToggled(mPreviousGravity, expanding); @@ -347,10 +334,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal mPreviousGravity = Gravity.NO_GRAVITY; updatePinnedStackBounds(); } else { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: Position hasn't changed", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Position hasn't changed", TAG); } } @@ -403,11 +388,9 @@ public class TvPipController implements PipTransitionController.PipTransitionCal */ @Override public void closePip() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: closePip(), state=%s, loseAction=%s", TAG, stateToName(mState), - mCloseAction); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: closePip(), state=%s, loseAction=%s", TAG, stateToName(mState), + mCloseAction); if (mCloseAction != null) { try { @@ -443,10 +426,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal private void checkIfPinnedTaskAppeared() { final TaskInfo pinnedTask = getPinnedTaskInfo(); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: checkIfPinnedTaskAppeared(), task=%s", TAG, pinnedTask); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: checkIfPinnedTaskAppeared(), task=%s", TAG, pinnedTask); if (pinnedTask == null || pinnedTask.topActivity == null) return; mPinnedTaskId = pinnedTask.taskId; @@ -455,10 +436,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal } private void checkIfPinnedTaskIsGone() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onTaskStackChanged()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onTaskStackChanged()", TAG); if (isPipShown() && getPinnedTaskInfo() == null) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, @@ -468,10 +447,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal } private void onPipDisappeared() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onPipDisappeared() state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onPipDisappeared() state=%s", TAG, stateToName(mState)); mPipNotificationController.dismiss(); mTvPipMenuController.closeMenu(); @@ -483,19 +460,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void onPipTransitionStarted(int direction, Rect pipBounds) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onPipTransition_Started(), state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onPipTransition_Started(), state=%s", TAG, stateToName(mState)); mTvPipMenuController.notifyPipAnimating(true); } @Override public void onPipTransitionCanceled(int direction) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onPipTransition_Canceled(), state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onPipTransition_Canceled(), state=%s", TAG, stateToName(mState)); mTvPipMenuController.notifyPipAnimating(false); } @@ -504,19 +477,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal if (PipAnimationController.isInPipDirection(direction) && mState == STATE_NO_PIP) { setState(STATE_PIP); } - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onPipTransition_Finished(), state=%s", TAG, stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onPipTransition_Finished(), state=%s", TAG, stateToName(mState)); mTvPipMenuController.notifyPipAnimating(false); } private void setState(@State int state) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: setState(), state=%s, prev=%s", - TAG, stateToName(state), stateToName(mState)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: setState(), state=%s, prev=%s", + TAG, stateToName(state), stateToName(mState)); mState = state; } @@ -550,11 +519,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { if (task.getWindowingMode() == WINDOWING_MODE_PINNED) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onPinnedActivityRestartAttempt()", TAG); - } - + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onPinnedActivityRestartAttempt()", TAG); // If the "Pip-ed" Activity is launched again by Launcher or intent, make it // fullscreen. movePipToFullscreen(); @@ -569,7 +535,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal public void onActionsChanged(List<RemoteAction> actions, RemoteAction closeAction) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onActionsChanged()", TAG); + "%s: onActionsChanged()", TAG); mTvPipMenuController.setAppActions(actions, closeAction); mCloseAction = closeAction; @@ -578,7 +544,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void onAspectRatioChanged(float ratio) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onAspectRatioChanged: %f", TAG, ratio); + "%s: onAspectRatioChanged: %f", TAG, ratio); mTvPipBoundsState.setAspectRatio(ratio); if (!mTvPipBoundsState.isTvPipExpanded()) { @@ -589,7 +555,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void onExpandedAspectRatioChanged(float ratio) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onExpandedAspectRatioChanged: %f", TAG, ratio); + "%s: onExpandedAspectRatioChanged: %f", TAG, ratio); mTvPipBoundsState.setDesiredTvExpandedAspectRatio(ratio, false); mTvPipMenuController.updateExpansionState(); @@ -635,11 +601,9 @@ public class TvPipController implements PipTransitionController.PipTransitionCal wmShell.addPinnedStackListener(new PinnedStackListenerForwarder.PinnedTaskListener() { @Override public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onImeVisibilityChanged(), visible=%b, height=%d", - TAG, imeVisible, imeHeight); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onImeVisibilityChanged(), visible=%b, height=%d", + TAG, imeVisible, imeHeight); if (imeVisible == mTvPipBoundsState.isImeShowing() && (!imeVisible || imeHeight == mTvPipBoundsState.getImeHeight())) { @@ -661,17 +625,13 @@ public class TvPipController implements PipTransitionController.PipTransitionCal } private static TaskInfo getPinnedTaskInfo() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: getPinnedTaskInfo()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: getPinnedTaskInfo()", TAG); try { final TaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: taskInfo=%s", TAG, taskInfo); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: taskInfo=%s", TAG, taskInfo); return taskInfo; } catch (RemoteException e) { ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, @@ -681,10 +641,8 @@ public class TvPipController implements PipTransitionController.PipTransitionCal } private static void removeTask(int taskId) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: removeTask(), taskId=%d", TAG, taskId); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: removeTask(), taskId=%d", TAG, taskId); try { ActivityTaskManager.getService().removeTask(taskId); } catch (Exception e) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java index 4ce45e142c64..176fdfee2512 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java @@ -54,7 +54,6 @@ import java.util.Objects; */ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Listener { private static final String TAG = "TvPipMenuController"; - private static final boolean DEBUG = TvPipController.DEBUG; private static final String BACKGROUND_WINDOW_TITLE = "PipBackgroundView"; private final Context mContext; @@ -119,10 +118,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis } void setDelegate(Delegate delegate) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: setDelegate(), delegate=%s", TAG, delegate); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: setDelegate(), delegate=%s", TAG, delegate); if (mDelegate != null) { throw new IllegalStateException( "The delegate has already been set and should not change."); @@ -145,10 +142,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis } private void attachPipMenu() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: attachPipMenu()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: attachPipMenu()", TAG); if (mPipMenuView != null) { detachPipMenu(); @@ -158,7 +153,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis attachPipMenuView(); mTvPipBoundsState.setPipMenuPermanentDecorInsets(Insets.of(-mPipMenuBorderWidth, - -mPipMenuBorderWidth, -mPipMenuBorderWidth, -mPipMenuBorderWidth)); + -mPipMenuBorderWidth, -mPipMenuBorderWidth, -mPipMenuBorderWidth)); mTvPipBoundsState.setPipMenuTemporaryDecorInsets(Insets.of(0, 0, 0, -mPipEduTextHeight)); mMainHandler.postDelayed(mCloseEduTextRunnable, mPipEduTextShowDurationMs); } @@ -180,35 +175,33 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis private void setUpViewSurfaceZOrder(View v, int zOrderRelativeToPip) { v.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(View v) { - v.getViewRootImpl().addSurfaceChangedCallback( - new PipMenuSurfaceChangedCallback(v, zOrderRelativeToPip)); - } - - @Override - public void onViewDetachedFromWindow(View v) { - } + @Override + public void onViewAttachedToWindow(View v) { + v.getViewRootImpl().addSurfaceChangedCallback( + new PipMenuSurfaceChangedCallback(v, zOrderRelativeToPip)); + } + + @Override + public void onViewDetachedFromWindow(View v) { + } }); } private void addPipMenuViewToSystemWindows(View v, String title) { - mSystemWindows.addView(v, getPipMenuLayoutParams(title, 0 /* width */, 0 /* height */), - 0 /* displayId */, SHELL_ROOT_LAYER_PIP); + mSystemWindows.addView(v, getPipMenuLayoutParams(mContext, title, 0 /* width */, + 0 /* height */), 0 /* displayId */, SHELL_ROOT_LAYER_PIP); } void notifyPipAnimating(boolean animating) { mPipMenuView.setEduTextActive(!animating); if (!animating) { - mPipMenuView.onPipTransitionFinished(); + mPipMenuView.onPipTransitionFinished(mTvPipBoundsState.isTvPipExpanded()); } } void showMovementMenuOnly() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: showMovementMenuOnly()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: showMovementMenuOnly()", TAG); setInMoveMode(true); mCloseAfterExitMoveMenu = true; showMenuInternal(); @@ -216,9 +209,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis @Override public void showMenu() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMenu()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMenu()", TAG); setInMoveMode(false); mCloseAfterExitMoveMenu = false; showMenuInternal(); @@ -267,7 +258,6 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis void updateExpansionState() { mPipMenuView.setExpandedModeEnabled(mTvPipBoundsState.isTvExpandedPipSupported() && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0); - mPipMenuView.setIsExpanded(mTvPipBoundsState.isTvPipExpanded()); } private Rect calculateMenuSurfaceBounds(Rect pipBounds) { @@ -275,15 +265,12 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis } void closeMenu() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: closeMenu()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: closeMenu()", TAG); if (mPipMenuView == null) { return; } - mPipMenuView.hideAllUserControls(); grantPipMenuFocus(false); mDelegate.onMenuClosed(); @@ -297,7 +284,6 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis if (mInMoveMode == moveMode) { return; } - mInMoveMode = moveMode; if (mDelegate != null) { mDelegate.onInMoveModeChanged(); @@ -306,22 +292,19 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis @Override public void onEnterMoveMode() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onEnterMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode, - mCloseAfterExitMoveMenu); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onEnterMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode, + mCloseAfterExitMoveMenu); setInMoveMode(true); mPipMenuView.showMoveMenu(mDelegate.getPipGravity()); } @Override public boolean onExitMoveMode() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onExitMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode, - mCloseAfterExitMoveMenu); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onExitMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode, + mCloseAfterExitMoveMenu); + if (mCloseAfterExitMoveMenu) { setInMoveMode(false); mCloseAfterExitMoveMenu = false; @@ -338,10 +321,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis @Override public boolean onPipMovement(int keycode) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onPipMovement - %b", TAG, mInMoveMode); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onPipMovement - %b", TAG, mInMoveMode); if (mInMoveMode) { mDelegate.movePip(keycode); } @@ -358,18 +339,14 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis @Override public void setAppActions(List<RemoteAction> actions, RemoteAction closeAction) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: setAppActions()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: setAppActions()", TAG); updateAdditionalActionsList(mAppActions, actions, closeAction); } private void onMediaActionsChanged(List<RemoteAction> actions) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: onMediaActionsChanged()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: onMediaActionsChanged()", TAG); // Hide disabled actions. List<RemoteAction> enabledActions = new ArrayList<>(); @@ -421,10 +398,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis public void resizePipMenu(@Nullable SurfaceControl pipLeash, @Nullable SurfaceControl.Transaction t, Rect destinationBounds) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: resizePipMenu: %s", TAG, destinationBounds.toShortString()); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: resizePipMenu: %s", TAG, destinationBounds.toShortString()); if (destinationBounds.isEmpty()) { return; } @@ -438,14 +413,14 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis final SurfaceControl frontSurface = getSurfaceControl(mPipMenuView); final SyncRtSurfaceTransactionApplier.SurfaceParams frontParams = new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(frontSurface) - .withWindowCrop(menuBounds) - .build(); + .withWindowCrop(menuBounds) + .build(); final SurfaceControl backSurface = getSurfaceControl(mPipBackgroundView); final SyncRtSurfaceTransactionApplier.SurfaceParams backParams = new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(backSurface) - .withWindowCrop(menuBounds) - .build(); + .withWindowCrop(menuBounds) + .build(); // TODO(b/226580399): switch to using SurfaceSyncer (see b/200284684) to synchronize the // animations of the pip surface with the content of the front and back menu surfaces @@ -468,13 +443,11 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis @Override public void movePipMenu(SurfaceControl pipLeash, SurfaceControl.Transaction transaction, Rect pipDestBounds) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: movePipMenu: %s", TAG, pipDestBounds.toShortString()); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: movePipMenu: %s", TAG, pipDestBounds.toShortString()); if (pipDestBounds.isEmpty()) { - if (transaction == null && DEBUG) { + if (transaction == null) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: no transaction given", TAG); } @@ -490,16 +463,12 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis // resizing and the PiP menu is also resized. We then want to do a scale from the current // new menu bounds. if (pipLeash != null && transaction != null) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: tmpSourceBounds based on mPipMenuView.getBoundsOnScreen()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: tmpSourceBounds based on mPipMenuView.getBoundsOnScreen()", TAG); mPipMenuView.getBoundsOnScreen(tmpSourceBounds); } else { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: tmpSourceBounds based on menu width and height", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: tmpSourceBounds based on menu width and height", TAG); tmpSourceBounds.set(0, 0, menuDestBounds.width(), menuDestBounds.height()); } @@ -525,8 +494,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis if (pipLeash != null && transaction != null) { final SyncRtSurfaceTransactionApplier.SurfaceParams pipParams = new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(pipLeash) - .withMergeTransaction(transaction) - .build(); + .withMergeTransaction(transaction) + .build(); mApplier.scheduleApply(frontParams, pipParams); } else { mApplier.scheduleApply(frontParams); @@ -568,15 +537,13 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis @Override public void updateMenuBounds(Rect destinationBounds) { final Rect menuBounds = calculateMenuSurfaceBounds(destinationBounds); - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: updateMenuBounds: %s", TAG, menuBounds.toShortString()); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: updateMenuBounds: %s", TAG, menuBounds.toShortString()); mSystemWindows.updateViewLayout(mPipBackgroundView, - getPipMenuLayoutParams(BACKGROUND_WINDOW_TITLE, menuBounds.width(), + getPipMenuLayoutParams(mContext, BACKGROUND_WINDOW_TITLE, menuBounds.width(), menuBounds.height())); mSystemWindows.updateViewLayout(mPipMenuView, - getPipMenuLayoutParams(MENU_WINDOW_TITLE, menuBounds.width(), + getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, menuBounds.width(), menuBounds.height())); if (mPipMenuView != null) { @@ -630,10 +597,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis } private void grantPipMenuFocus(boolean grantFocus) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: grantWindowFocus(%b)", TAG, grantFocus); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: grantWindowFocus(%b)", TAG, grantFocus); try { WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java index 320c05c4a415..9cd05b0eea75 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java @@ -43,6 +43,7 @@ import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; +import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; import android.widget.HorizontalScrollView; import android.widget.ImageView; @@ -55,6 +56,7 @@ import androidx.annotation.Nullable; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.R; +import com.android.wm.shell.common.TvWindowMenuActionButton; import com.android.wm.shell.pip.PipUtils; import com.android.wm.shell.protolog.ShellProtoLogGroup; @@ -65,11 +67,10 @@ import java.util.List; /** * A View that represents Pip Menu on TV. It's responsible for displaying 3 ever-present Pip Menu * actions: Fullscreen, Move and Close, but could also display "additional" actions, that may be set - * via a {@link #setAdditionalActions(List, Handler)} call. + * via a {@link #setAdditionalActions(List, RemoteAction, Handler)} call. */ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { private static final String TAG = "TvPipMenuView"; - private static final boolean DEBUG = TvPipController.DEBUG; private static final int FIRST_CUSTOM_ACTION_POSITION = 3; @@ -78,7 +79,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { private final LinearLayout mActionButtonsContainer; private final View mMenuFrameView; - private final List<TvPipMenuActionButton> mAdditionalButtons = new ArrayList<>(); + private final List<TvWindowMenuActionButton> mAdditionalButtons = new ArrayList<>(); private final View mPipFrameView; private final View mPipView; private final TextView mEduTextView; @@ -93,6 +94,10 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { private final ImageView mArrowRight; private final ImageView mArrowDown; private final ImageView mArrowLeft; + private final TvWindowMenuActionButton mA11yDoneButton; + + private final View mPipBackground; + private final View mDimLayer; private final ScrollView mScrollView; private final HorizontalScrollView mHorizontalScrollView; @@ -102,14 +107,16 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { private boolean mMoveMenuIsVisible; private boolean mButtonMenuIsVisible; - private final TvPipMenuActionButton mExpandButton; - private final TvPipMenuActionButton mCloseButton; + private final TvWindowMenuActionButton mExpandButton; + private final TvWindowMenuActionButton mCloseButton; private boolean mSwitchingOrientation; private final int mPipMenuFadeAnimationDuration; private final int mResizeAnimationDuration; + private final AccessibilityManager mA11yManager; + public TvPipMenuView(@NonNull Context context) { this(context, null); } @@ -128,6 +135,8 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { inflate(context, R.layout.tv_pip_menu, this); + mA11yManager = context.getSystemService(AccessibilityManager.class); + mActionButtonsContainer = findViewById(R.id.tv_pip_menu_action_buttons); mActionButtonsContainer.findViewById(R.id.tv_pip_menu_fullscreen_button) .setOnClickListener(this); @@ -141,6 +150,9 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { mExpandButton = findViewById(R.id.tv_pip_menu_expand_button); mExpandButton.setOnClickListener(this); + mPipBackground = findViewById(R.id.tv_pip_menu_background); + mDimLayer = findViewById(R.id.tv_pip_menu_dim_layer); + mScrollView = findViewById(R.id.tv_pip_menu_scroll); mHorizontalScrollView = findViewById(R.id.tv_pip_menu_horizontal_scroll); @@ -152,6 +164,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { mArrowRight = findViewById(R.id.tv_pip_menu_arrow_right); mArrowDown = findViewById(R.id.tv_pip_menu_arrow_down); mArrowLeft = findViewById(R.id.tv_pip_menu_arrow_left); + mA11yDoneButton = findViewById(R.id.tv_pip_menu_done_button); mEduTextView = findViewById(R.id.tv_pip_menu_edu_text); mEduTextContainerView = findViewById(R.id.tv_pip_menu_edu_text_container); @@ -159,7 +172,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { mResizeAnimationDuration = context.getResources().getInteger( R.integer.config_pipResizeAnimationDuration); mPipMenuFadeAnimationDuration = context.getResources() - .getInteger(R.integer.pip_menu_fade_animation_duration); + .getInteger(R.integer.tv_window_menu_fade_animation_duration); mPipMenuOuterSpace = context.getResources() .getDimensionPixelSize(R.dimen.pip_menu_outer_space); @@ -223,7 +236,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { mCurrentPipBounds.width() / (float) mCurrentPipBounds.height(), finishBounds.width() / (float) finishBounds.height()); if (ratioChanged) { - mPipView.animate() + mPipBackground.animate() .alpha(1f) .setInterpolator(TvPipInterpolators.EXIT) .setDuration(mResizeAnimationDuration / 2) @@ -259,17 +272,19 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { } } - void onPipTransitionFinished() { + void onPipTransitionFinished(boolean isTvPipExpanded) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: onPipTransitionFinished()", TAG); // Fade in content by fading out view on top. - mPipView.animate() + mPipBackground.animate() .alpha(0f) .setDuration(mResizeAnimationDuration / 2) .setInterpolator(TvPipInterpolators.ENTER) .start(); + setIsExpanded(isTvPipExpanded); + // Update buttons. if (mSwitchingOrientation) { mActionButtonsContainer.animate() @@ -432,10 +447,8 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { } void setIsExpanded(boolean expanded) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: setIsExpanded, expanded: %b", TAG, expanded); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: setIsExpanded, expanded: %b", TAG, expanded); mExpandButton.setImageResource( expanded ? R.drawable.pip_ic_collapse : R.drawable.pip_ic_expand); mExpandButton.setTextAndDescription( @@ -446,28 +459,29 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { * @param gravity for the arrow hints */ void showMoveMenu(int gravity) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG); mButtonMenuIsVisible = false; mMoveMenuIsVisible = true; showButtonsMenu(false); showMovementHints(gravity); setFrameHighlighted(true); + + mHorizontalScrollView.setFocusable(false); + mScrollView.setFocusable(false); } void showButtonsMenu() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: showButtonsMenu()", TAG); - } - + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: showButtonsMenu()", TAG); mButtonMenuIsVisible = true; mMoveMenuIsVisible = false; showButtonsMenu(true); hideMovementHints(); setFrameHighlighted(true); + mHorizontalScrollView.setFocusable(true); + mScrollView.setFocusable(true); + // Always focus on the first button when opening the menu, except directly after moving. if (mFocusedButton == null) { // Focus on first button (there is a Space at position 0) @@ -531,10 +545,8 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { */ void setAdditionalActions(List<RemoteAction> actions, RemoteAction closeAction, Handler mainHandler) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: setAdditionalActions()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: setAdditionalActions()", TAG); // Replace system close action with custom close action if available if (closeAction != null) { @@ -553,7 +565,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { if (actionsNumber > buttonsNumber) { // Add buttons until we have enough to display all the actions. while (actionsNumber > buttonsNumber) { - TvPipMenuActionButton button = new TvPipMenuActionButton(mContext); + TvWindowMenuActionButton button = new TvWindowMenuActionButton(mContext); button.setOnClickListener(this); mActionButtonsContainer.addView(button, @@ -576,7 +588,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { // "Assign" actions to the buttons. for (int index = 0; index < actionsNumber; index++) { final RemoteAction action = actions.get(index); - final TvPipMenuActionButton button = mAdditionalButtons.get(index); + final TvWindowMenuActionButton button = mAdditionalButtons.get(index); // Remove action if it matches the custom close action. if (PipUtils.remoteActionsMatch(action, closeAction)) { @@ -592,7 +604,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { } } - private void setActionForButton(RemoteAction action, TvPipMenuActionButton button, + private void setActionForButton(RemoteAction action, TvWindowMenuActionButton button, Handler mainHandler) { button.setVisibility(View.VISIBLE); // Ensure the button is visible. if (action.getContentDescription().length() > 0) { @@ -655,10 +667,16 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { mFocusedButton = mActionButtonsContainer.getFocusedChild(); } + if (event.getKeyCode() == KEYCODE_BACK) { + mListener.onBackPress(); + return true; + } + + if (mA11yManager.isEnabled()) { + return super.dispatchKeyEvent(event); + } + switch (event.getKeyCode()) { - case KEYCODE_BACK: - mListener.onBackPress(); - return true; case KEYCODE_DPAD_UP: case KEYCODE_DPAD_DOWN: case KEYCODE_DPAD_LEFT: @@ -679,15 +697,39 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { * Shows user hints for moving the PiP, e.g. arrows. */ public void showMovementHints(int gravity) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: showMovementHints(), position: %s", TAG, Gravity.toString(gravity)); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: showMovementHints(), position: %s", TAG, Gravity.toString(gravity)); animateAlphaTo(checkGravity(gravity, Gravity.BOTTOM) ? 1f : 0f, mArrowUp); animateAlphaTo(checkGravity(gravity, Gravity.TOP) ? 1f : 0f, mArrowDown); animateAlphaTo(checkGravity(gravity, Gravity.RIGHT) ? 1f : 0f, mArrowLeft); animateAlphaTo(checkGravity(gravity, Gravity.LEFT) ? 1f : 0f, mArrowRight); + + boolean a11yEnabled = mA11yManager.isEnabled(); + setArrowA11yEnabled(mArrowUp, a11yEnabled, KEYCODE_DPAD_UP); + setArrowA11yEnabled(mArrowDown, a11yEnabled, KEYCODE_DPAD_DOWN); + setArrowA11yEnabled(mArrowLeft, a11yEnabled, KEYCODE_DPAD_LEFT); + setArrowA11yEnabled(mArrowRight, a11yEnabled, KEYCODE_DPAD_RIGHT); + + animateAlphaTo(a11yEnabled ? 1f : 0f, mA11yDoneButton); + if (a11yEnabled) { + mA11yDoneButton.setOnClickListener(v -> { + if (mListener != null) { + mListener.onExitMoveMode(); + } + }); + } + } + + private void setArrowA11yEnabled(View arrowView, boolean enabled, int keycode) { + arrowView.setClickable(enabled); + if (enabled) { + arrowView.setOnClickListener(v -> { + if (mListener != null) { + mListener.onPipMovement(keycode); + } + }); + } } private boolean checkGravity(int gravity, int feature) { @@ -698,29 +740,28 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener { * Hides user hints for moving the PiP, e.g. arrows. */ public void hideMovementHints() { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: hideMovementHints()", TAG); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: hideMovementHints()", TAG); + animateAlphaTo(0, mArrowUp); animateAlphaTo(0, mArrowRight); animateAlphaTo(0, mArrowDown); animateAlphaTo(0, mArrowLeft); + animateAlphaTo(0, mA11yDoneButton); } /** * Show or hide the pip buttons menu. */ public void showButtonsMenu(boolean show) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: showUserActions: %b", TAG, show); - } + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: showUserActions: %b", TAG, show); if (show) { mActionButtonsContainer.setVisibility(VISIBLE); refocusPreviousButton(); } animateAlphaTo(show ? 1 : 0, mActionButtonsContainer); + animateAlphaTo(show ? 1 : 0, mDimLayer); } private void setFrameHighlighted(boolean highlighted) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java index 61a609d9755e..e3308f0763a0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java @@ -114,6 +114,7 @@ public class TvPipNotificationController { .setOngoing(true) .setCategory(Notification.CATEGORY_SYSTEM) .setShowWhen(true) + .setOnlyAlertOnce(true) .setSmallIcon(R.drawable.pip_icon) .setAllowSystemGeneratedContextualActions(false) .setContentIntent(createPendingIntent(context, ACTION_FULLSCREEN)) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS new file mode 100644 index 000000000000..28be0efc38f6 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS @@ -0,0 +1,3 @@ +# WM shell sub-module TV splitscreen owner +galinap@google.com +bronger@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java new file mode 100644 index 000000000000..1d8a8d506c5c --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java @@ -0,0 +1,218 @@ +/* + * 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.splitscreen.tv; + +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; +import static android.view.WindowManager.SHELL_ROOT_LAYER_DIVIDER; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.PixelFormat; +import android.os.Handler; +import android.os.RemoteException; +import android.view.LayoutInflater; +import android.view.WindowManager; +import android.view.WindowManagerGlobal; + +import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.R; +import com.android.wm.shell.common.SystemWindows; +import com.android.wm.shell.common.split.SplitScreenConstants; +import com.android.wm.shell.protolog.ShellProtoLogGroup; + +/** + * Handles the interaction logic with the {@link TvSplitMenuView}. + * A bridge between {@link TvStageCoordinator} and {@link TvSplitMenuView}. + */ +public class TvSplitMenuController implements TvSplitMenuView.Listener { + + private static final String TAG = TvSplitMenuController.class.getSimpleName(); + private static final String ACTION_SHOW_MENU = "com.android.wm.shell.splitscreen.SHOW_MENU"; + private static final String SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF"; + + private final Context mContext; + private final StageController mStageController; + private final SystemWindows mSystemWindows; + private final Handler mMainHandler; + + private final TvSplitMenuView mSplitMenuView; + + private final ActionBroadcastReceiver mActionBroadcastReceiver; + + private final int mTvButtonFadeAnimationDuration; + + public TvSplitMenuController(Context context, StageController stageController, + SystemWindows systemWindows, Handler mainHandler) { + mContext = context; + mMainHandler = mainHandler; + mStageController = stageController; + mSystemWindows = systemWindows; + + mTvButtonFadeAnimationDuration = context.getResources() + .getInteger(R.integer.tv_window_menu_fade_animation_duration); + + mSplitMenuView = (TvSplitMenuView) LayoutInflater.from(context) + .inflate(R.layout.tv_split_menu_view, null); + mSplitMenuView.setListener(this); + + mActionBroadcastReceiver = new ActionBroadcastReceiver(); + } + + /** + * Adds the menu view for the splitscreen to SystemWindows. + */ + void addSplitMenuViewToSystemWindows() { + final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + mContext.getResources().getDisplayMetrics().widthPixels, + mContext.getResources().getDisplayMetrics().heightPixels, + TYPE_DOCK_DIVIDER, + FLAG_NOT_TOUCHABLE, + PixelFormat.TRANSLUCENT); + lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY; + mSplitMenuView.setAlpha(0); + mSystemWindows.addView(mSplitMenuView, lp, DEFAULT_DISPLAY, SHELL_ROOT_LAYER_DIVIDER); + } + + /** + * Removes the menu view for the splitscreen from SystemWindows. + */ + void removeSplitMenuViewFromSystemWindows() { + mSystemWindows.removeView(mSplitMenuView); + } + + /** + * Registers BroadcastReceiver when split screen mode is entered. + */ + void registerBroadcastReceiver() { + mActionBroadcastReceiver.register(); + } + + /** + * Unregisters BroadcastReceiver when split screen mode is entered. + */ + void unregisterBroadcastReceiver() { + mActionBroadcastReceiver.unregister(); + } + + @Override + public void onBackPress() { + setMenuVisibility(false); + } + + @Override + public void onFocusStage(@SplitScreenConstants.SplitPosition int stageToFocus) { + setMenuVisibility(false); + mStageController.grantFocusToStage(stageToFocus); + } + + @Override + public void onCloseStage(@SplitScreenConstants.SplitPosition int stageToClose) { + setMenuVisibility(false); + mStageController.exitStage(stageToClose); + } + + @Override + public void onSwapPress() { + mStageController.swapStages(); + } + + private void setMenuVisibility(boolean visible) { + applyMenuVisibility(visible); + setMenuFocus(visible); + } + + private void applyMenuVisibility(boolean visible) { + float alphaTarget = visible ? 1F : 0F; + + if (mSplitMenuView.getAlpha() == alphaTarget) { + return; + } + + mSplitMenuView.animate() + .alpha(alphaTarget) + .setDuration(mTvButtonFadeAnimationDuration) + .withStartAction(() -> { + if (alphaTarget != 0) { + mSplitMenuView.setVisibility(VISIBLE); + } + }) + .withEndAction(() -> { + if (alphaTarget == 0) { + mSplitMenuView.setVisibility(INVISIBLE); + } + }); + + } + + private void setMenuFocus(boolean focused) { + try { + WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null, + mSystemWindows.getFocusGrantToken(mSplitMenuView), focused); + } catch (RemoteException e) { + ProtoLog.e(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Unable to update focus, %s", TAG, e); + } + } + + interface StageController { + void grantFocusToStage(@SplitScreenConstants.SplitPosition int stageToFocus); + void exitStage(@SplitScreenConstants.SplitPosition int stageToClose); + void swapStages(); + } + + private class ActionBroadcastReceiver extends BroadcastReceiver { + + final IntentFilter mIntentFilter; + { + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(ACTION_SHOW_MENU); + } + boolean mRegistered = false; + + void register() { + if (mRegistered) return; + + mContext.registerReceiverForAllUsers(this, mIntentFilter, SYSTEMUI_PERMISSION, + mMainHandler); + mRegistered = true; + } + + void unregister() { + if (!mRegistered) return; + + mContext.unregisterReceiver(this); + mRegistered = false; + } + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + + if (ACTION_SHOW_MENU.equals(action)) { + setMenuVisibility(true); + } + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuView.java new file mode 100644 index 000000000000..88e9757a9b31 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuView.java @@ -0,0 +1,117 @@ +/* + * 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.splitscreen.tv; + +import static android.view.KeyEvent.ACTION_DOWN; +import static android.view.KeyEvent.KEYCODE_BACK; + +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.View; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import com.android.wm.shell.R; +import com.android.wm.shell.common.split.SplitScreenConstants; + +/** + * A View for the Menu Window. + */ +public class TvSplitMenuView extends LinearLayout implements View.OnClickListener { + + private Listener mListener; + + public TvSplitMenuView(Context context) { + super(context); + } + + public TvSplitMenuView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public TvSplitMenuView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + initButtons(); + } + + @Override + public void onClick(View v) { + if (mListener == null) return; + + final int id = v.getId(); + if (id == R.id.tv_split_main_menu_focus_button) { + mListener.onFocusStage(SPLIT_POSITION_TOP_OR_LEFT); + } else if (id == R.id.tv_split_main_menu_close_button) { + mListener.onCloseStage(SPLIT_POSITION_TOP_OR_LEFT); + } else if (id == R.id.tv_split_side_menu_focus_button) { + mListener.onFocusStage(SPLIT_POSITION_BOTTOM_OR_RIGHT); + } else if (id == R.id.tv_split_side_menu_close_button) { + mListener.onCloseStage(SPLIT_POSITION_BOTTOM_OR_RIGHT); + } else if (id == R.id.tv_split_menu_swap_stages) { + mListener.onSwapPress(); + } + } + + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == ACTION_DOWN) { + if (event.getKeyCode() == KEYCODE_BACK) { + if (mListener != null) { + mListener.onBackPress(); + return true; + } + } + } + return super.dispatchKeyEvent(event); + } + + private void initButtons() { + findViewById(R.id.tv_split_main_menu_focus_button).setOnClickListener(this); + findViewById(R.id.tv_split_main_menu_close_button).setOnClickListener(this); + findViewById(R.id.tv_split_side_menu_focus_button).setOnClickListener(this); + findViewById(R.id.tv_split_side_menu_close_button).setOnClickListener(this); + findViewById(R.id.tv_split_menu_swap_stages).setOnClickListener(this); + } + + void setListener(Listener listener) { + mListener = listener; + } + + interface Listener { + /** "Back" button from the remote control */ + void onBackPress(); + + /** Menu Action Buttons */ + + void onFocusStage(@SplitScreenConstants.SplitPosition int stageToFocus); + + void onCloseStage(@SplitScreenConstants.SplitPosition int stageToClose); + + void onSwapPress(); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java new file mode 100644 index 000000000000..46d2a5a11671 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java @@ -0,0 +1,117 @@ +/* + * 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.splitscreen.tv; + +import static android.view.Display.DEFAULT_DISPLAY; + +import android.content.Context; +import android.os.Handler; + +import com.android.launcher3.icons.IconProvider; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; +import com.android.wm.shell.ShellTaskOrganizer; +import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.DisplayInsetsController; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.SyncTransactionQueue; +import com.android.wm.shell.common.SystemWindows; +import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.draganddrop.DragAndDropController; +import com.android.wm.shell.recents.RecentTasksController; +import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.splitscreen.StageCoordinator; +import com.android.wm.shell.sysui.ShellCommandHandler; +import com.android.wm.shell.sysui.ShellController; +import com.android.wm.shell.sysui.ShellInit; +import com.android.wm.shell.transition.Transitions; + +import java.util.Optional; + +/** + * Class inherits from {@link SplitScreenController} and provides {@link TvStageCoordinator} + * for Split Screen on TV. + */ +public class TvSplitScreenController extends SplitScreenController { + private final ShellTaskOrganizer mTaskOrganizer; + private final SyncTransactionQueue mSyncQueue; + private final Context mContext; + private final ShellExecutor mMainExecutor; + private final DisplayController mDisplayController; + private final DisplayImeController mDisplayImeController; + private final DisplayInsetsController mDisplayInsetsController; + private final Transitions mTransitions; + private final TransactionPool mTransactionPool; + private final IconProvider mIconProvider; + private final Optional<RecentTasksController> mRecentTasksOptional; + + private final Handler mMainHandler; + private final SystemWindows mSystemWindows; + + public TvSplitScreenController(Context context, + ShellInit shellInit, + ShellCommandHandler shellCommandHandler, + ShellController shellController, + ShellTaskOrganizer shellTaskOrganizer, + SyncTransactionQueue syncQueue, + RootTaskDisplayAreaOrganizer rootTDAOrganizer, + DisplayController displayController, + DisplayImeController displayImeController, + DisplayInsetsController displayInsetsController, + DragAndDropController dragAndDropController, + Transitions transitions, + TransactionPool transactionPool, + IconProvider iconProvider, + Optional<RecentTasksController> recentTasks, + ShellExecutor mainExecutor, + Handler mainHandler, + SystemWindows systemWindows) { + super(context, shellInit, shellCommandHandler, shellController, shellTaskOrganizer, + syncQueue, rootTDAOrganizer, displayController, displayImeController, + displayInsetsController, dragAndDropController, transitions, transactionPool, + iconProvider, recentTasks, mainExecutor); + + mTaskOrganizer = shellTaskOrganizer; + mSyncQueue = syncQueue; + mContext = context; + mMainExecutor = mainExecutor; + mDisplayController = displayController; + mDisplayImeController = displayImeController; + mDisplayInsetsController = displayInsetsController; + mTransitions = transitions; + mTransactionPool = transactionPool; + mIconProvider = iconProvider; + mRecentTasksOptional = recentTasks; + + mMainHandler = mainHandler; + mSystemWindows = systemWindows; + } + + /** + * Provides Tv-specific StageCoordinator. + * @return {@link TvStageCoordinator} + */ + @Override + protected StageCoordinator createStageCoordinator() { + return new TvStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue, + mTaskOrganizer, mDisplayController, mDisplayImeController, + mDisplayInsetsController, mTransitions, mTransactionPool, + mIconProvider, mMainExecutor, mMainHandler, + mRecentTasksOptional, mSystemWindows); + } + +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java new file mode 100644 index 000000000000..4d563fbb7f04 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java @@ -0,0 +1,94 @@ +/* + * 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.splitscreen.tv; + +import android.content.Context; +import android.os.Handler; + +import com.android.launcher3.icons.IconProvider; +import com.android.wm.shell.ShellTaskOrganizer; +import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.DisplayInsetsController; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.SyncTransactionQueue; +import com.android.wm.shell.common.SystemWindows; +import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.common.split.SplitScreenConstants; +import com.android.wm.shell.recents.RecentTasksController; +import com.android.wm.shell.splitscreen.StageCoordinator; +import com.android.wm.shell.transition.Transitions; + +import java.util.Optional; + +/** + * Expands {@link StageCoordinator} functionality with Tv-specific methods. + */ +public class TvStageCoordinator extends StageCoordinator + implements TvSplitMenuController.StageController { + + private final TvSplitMenuController mTvSplitMenuController; + + public TvStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue, + ShellTaskOrganizer taskOrganizer, DisplayController displayController, + DisplayImeController displayImeController, + DisplayInsetsController displayInsetsController, Transitions transitions, + TransactionPool transactionPool, + IconProvider iconProvider, ShellExecutor mainExecutor, + Handler mainHandler, + Optional<RecentTasksController> recentTasks, + SystemWindows systemWindows) { + super(context, displayId, syncQueue, taskOrganizer, displayController, displayImeController, + displayInsetsController, transitions, transactionPool, iconProvider, + mainExecutor, recentTasks); + + mTvSplitMenuController = new TvSplitMenuController(context, this, + systemWindows, mainHandler); + + } + + @Override + protected void onSplitScreenEnter() { + mTvSplitMenuController.addSplitMenuViewToSystemWindows(); + mTvSplitMenuController.registerBroadcastReceiver(); + } + + @Override + protected void onSplitScreenExit() { + mTvSplitMenuController.unregisterBroadcastReceiver(); + mTvSplitMenuController.removeSplitMenuViewFromSystemWindows(); + } + + @Override + public void grantFocusToStage(@SplitScreenConstants.SplitPosition int stageToFocus) { + super.grantFocusToStage(stageToFocus); + } + + @Override + public void exitStage(@SplitScreenConstants.SplitPosition int stageToClose) { + super.exitStage(stageToClose); + } + + /** + * Swaps the stages inside the SplitLayout. + */ + @Override + public void swapStages() { + onDoubleTappedDivider(); + } + +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 4c927b6e84b8..1ae779e25bbf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -96,6 +96,7 @@ import android.view.WindowManager.TransitionType; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.Transformation; +import android.window.ScreenCapture; import android.window.TransitionInfo; import android.window.TransitionMetrics; import android.window.TransitionRequestInfo; @@ -630,16 +631,16 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { .setBufferSize(extensionRect.width(), extensionRect.height()) .build(); - SurfaceControl.LayerCaptureArgs captureArgs = - new SurfaceControl.LayerCaptureArgs.Builder(surfaceToExtend) + ScreenCapture.LayerCaptureArgs captureArgs = + new ScreenCapture.LayerCaptureArgs.Builder(surfaceToExtend) .setSourceCrop(edgeBounds) .setFrameScale(1) .setPixelFormat(PixelFormat.RGBA_8888) .setChildrenOnly(true) .setAllowProtected(true) .build(); - final SurfaceControl.ScreenshotHardwareBuffer edgeBuffer = - SurfaceControl.captureLayers(captureArgs); + final ScreenCapture.ScreenshotHardwareBuffer edgeBuffer = + ScreenCapture.captureLayers(captureArgs); if (edgeBuffer == null) { ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/IShellTransitions.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/IShellTransitions.aidl index bdcdb63d2cd6..cc4d268a0000 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/IShellTransitions.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/IShellTransitions.aidl @@ -34,4 +34,9 @@ interface IShellTransitions { * Unregisters a remote transition handler. */ oneway void unregisterRemote(in RemoteTransition remoteTransition) = 2; + + /** + * Retrieves the apply-token used by transactions in Shell + */ + IBinder getShellApplyToken() = 3; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java index b647f43da522..2b27baeb515a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java @@ -46,6 +46,7 @@ import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.animation.Animation; import android.view.animation.AnimationUtils; +import android.window.ScreenCapture; import android.window.TransitionInfo; import com.android.internal.R; @@ -144,14 +145,14 @@ class ScreenRotationAnimation { t.reparent(mScreenshotLayer, mAnimLeash); mStartLuma = change.getSnapshotLuma(); } else { - SurfaceControl.LayerCaptureArgs args = - new SurfaceControl.LayerCaptureArgs.Builder(mSurfaceControl) + ScreenCapture.LayerCaptureArgs args = + new ScreenCapture.LayerCaptureArgs.Builder(mSurfaceControl) .setCaptureSecureLayers(true) .setAllowProtected(true) .setSourceCrop(new Rect(0, 0, mStartWidth, mStartHeight)) .build(); - SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = - SurfaceControl.captureLayers(args); + ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = + ScreenCapture.captureLayers(args); if (screenshotBuffer == null) { Slog.w(TAG, "Unable to take screenshot of display"); return; @@ -481,8 +482,8 @@ class ScreenRotationAnimation { } Rect crop = new Rect(0, 0, bounds.width(), bounds.height()); - SurfaceControl.ScreenshotHardwareBuffer buffer = - SurfaceControl.captureLayers(surfaceControl, crop, 1); + ScreenCapture.ScreenshotHardwareBuffer buffer = + ScreenCapture.captureLayers(surfaceControl, crop, 1); if (buffer == null) { return 0; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 29d25bc39223..d2e8624171f6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -958,6 +958,11 @@ public class Transitions implements RemoteCallable<Transitions> { transitions.mRemoteTransitionHandler.removeFiltered(remoteTransition); }); } + + @Override + public IBinder getShellApplyToken() { + return SurfaceControl.Transaction.getDefaultApplyToken(); + } } private class SettingsObserver extends ContentObserver { diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp index 3ca5b9c38aff..d6adaa7d533b 100644 --- a/libs/WindowManager/Shell/tests/flicker/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -48,6 +48,6 @@ android_test { "wm-flicker-common-assertions", "wm-flicker-common-app-helpers", "platform-test-annotations", - "wmshell-flicker-test-components", + "flickertestapplib", ], } diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml index 574a9f4da627..1284c41af855 100644 --- a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml +++ b/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml @@ -19,7 +19,7 @@ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true"/> <option name="test-file-name" value="WMShellFlickerTests.apk"/> - <option name="test-file-name" value="WMShellFlickerTestApp.apk" /> + <option name="test-file-name" value="FlickerTestApp.apk" /> </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest"> <option name="package" value="com.android.wm.shell.flicker"/> 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 new file mode 100644 index 000000000000..2b162aec34ca --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt @@ -0,0 +1,181 @@ +/* + * 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 + +import android.app.Instrumentation +import android.platform.test.annotations.Presubmit +import androidx.test.platform.app.InstrumentationRegistry +import com.android.launcher3.tapl.LauncherInstrumentation +import com.android.server.wm.flicker.FlickerBuilderProvider +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.entireScreenCovered +import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd +import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd +import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd +import com.android.server.wm.flicker.statusBarLayerPositionAtStartAndEnd +import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd +import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper +import org.junit.Assume +import org.junit.Test + +/** + * Base test class containing common assertions for [ComponentMatcher.NAV_BAR], + * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions + * (layers visible in consecutive states, entire screen covered, etc.) + */ +abstract class BaseTest @JvmOverloads constructor( + protected val testSpec: FlickerTestParameter, + protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), + protected val tapl: LauncherInstrumentation = LauncherInstrumentation() +) { + init { + testSpec.setIsTablet( + WindowManagerStateHelper( + instrumentation, + clearCacheAfterParsing = false + ).currentState.wmState.isTablet + ) + } + + /** + * Specification of the test transition to execute + */ + abstract val transition: FlickerBuilder.() -> Unit + + /** + * Entry point for the test runner. It will use this method to initialize and cache + * flicker executions + */ + @FlickerBuilderProvider + fun buildFlicker(): FlickerBuilder { + return FlickerBuilder(instrumentation).apply { + setup { + testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet) + } + transition() + } + } + + /** + * Checks that all parts of the screen are covered during the transition + */ + open fun entireScreenCovered() = testSpec.entireScreenCovered() + + /** + * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition + */ + @Presubmit + @Test + open fun navBarLayerIsVisibleAtStartAndEnd() { + Assume.assumeFalse(testSpec.isTablet) + testSpec.navBarLayerIsVisibleAtStartAndEnd() + } + + /** + * Checks the position of the [ComponentMatcher.NAV_BAR] at the start and end of the transition + */ + @Presubmit + @Test + open fun navBarLayerPositionAtStartAndEnd() { + Assume.assumeFalse(testSpec.isTablet) + testSpec.navBarLayerPositionAtStartAndEnd() + } + + /** + * Checks that the [ComponentMatcher.NAV_BAR] window is visible during the whole transition + * + * Note: Phones only + */ + @Presubmit + @Test + open fun navBarWindowIsAlwaysVisible() { + Assume.assumeFalse(testSpec.isTablet) + testSpec.navBarWindowIsAlwaysVisible() + } + + /** + * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition + */ + @Presubmit + @Test + open fun taskBarLayerIsVisibleAtStartAndEnd() { + Assume.assumeTrue(testSpec.isTablet) + testSpec.taskBarLayerIsVisibleAtStartAndEnd() + } + + /** + * Checks that the [ComponentMatcher.TASK_BAR] window is visible during the whole transition + * + * Note: Large screen only + */ + @Presubmit + @Test + open fun taskBarWindowIsAlwaysVisible() { + Assume.assumeTrue(testSpec.isTablet) + testSpec.taskBarWindowIsAlwaysVisible() + } + + /** + * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible during the whole transition + */ + @Presubmit + @Test + open fun statusBarLayerIsVisibleAtStartAndEnd() = + testSpec.statusBarLayerIsVisibleAtStartAndEnd() + + /** + * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the transition + */ + @Presubmit + @Test + open fun statusBarLayerPositionAtStartAndEnd() = testSpec.statusBarLayerPositionAtStartAndEnd() + + /** + * Checks that the [ComponentMatcher.STATUS_BAR] window is visible during the whole transition + */ + @Presubmit + @Test + open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + + /** + * Checks that all layers that are visible on the trace, are visible for at least 2 + * consecutive entries. + */ + @Presubmit + @Test + open fun visibleLayersShownMoreThanOneConsecutiveEntry() { + testSpec.assertLayers { + this.visibleLayersShownMoreThanOneConsecutiveEntry() + } + } + + /** + * Checks that all windows that are visible on the trace, are visible for at least 2 + * consecutive entries. + */ + @Presubmit + @Test + open fun visibleWindowsShownMoreThanOneConsecutiveEntry() { + testSpec.assertWm { + this.visibleWindowsShownMoreThanOneConsecutiveEntry() + } + } +} 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/CommonAssertions.kt index cba396a82a87..2ccf1216d7c1 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/CommonAssertions.kt @@ -20,7 +20,10 @@ package com.android.wm.shell.flicker import android.view.Surface import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.helpers.WindowUtils -import com.android.server.wm.traces.common.FlickerComponentName +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled +import com.android.server.wm.flicker.traces.layers.LayerTraceEntrySubject +import com.android.server.wm.flicker.traces.layers.LayersTraceSubject +import com.android.server.wm.traces.common.IComponentMatcher import com.android.server.wm.traces.common.region.Region fun FlickerTestParameter.appPairsDividerIsVisibleAtEnd() { @@ -47,8 +50,16 @@ fun FlickerTestParameter.splitScreenDividerBecomesVisible() { layerBecomesVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } +fun FlickerTestParameter.splitScreenDividerBecomesInvisible() { + assertLayers { + this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + .then() + .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + } +} + fun FlickerTestParameter.layerBecomesVisible( - component: FlickerComponentName + component: IComponentMatcher ) { assertLayers { this.isInvisible(component) @@ -57,70 +68,225 @@ fun FlickerTestParameter.layerBecomesVisible( } } +fun FlickerTestParameter.layerBecomesInvisible( + component: IComponentMatcher +) { + assertLayers { + this.isVisible(component) + .then() + .isInvisible(component) + } +} + fun FlickerTestParameter.layerIsVisibleAtEnd( - component: FlickerComponentName + component: IComponentMatcher ) { assertLayersEnd { this.isVisible(component) } } +fun FlickerTestParameter.layerKeepVisible( + component: IComponentMatcher +) { + assertLayers { + this.isVisible(component) + } +} + fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible( - rotation: Int, - component: FlickerComponentName, - splitLeftTop: Boolean + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean ) { assertLayers { - val dividerRegion = this.last().layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region - this.isInvisible(component) + this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component)) .then() - .invoke("splitAppLayerBoundsBecomesVisible") { - it.visibleRegion(component).overlaps( - if (splitLeftTop) { - getSplitLeftTopRegion(dividerRegion, rotation) - } else { - getSplitRightBottomRegion(dividerRegion, rotation) - } - ) - } + .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component)) + .then() + .splitAppLayerBoundsSnapToDivider( + component, landscapePosLeft, portraitPosTop, endRotation) + } +} + +fun FlickerTestParameter.splitAppLayerBoundsBecomesVisibleByDrag( + component: IComponentMatcher +) { + assertLayers { + if (isShellTransitionsEnabled) { + this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true) + .then() + .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component)) + .then() + // TODO(b/245472831): Verify the component should snap to divider. + .isVisible(component) + } else { + this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true) + .then() + .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component)) + .then() + // TODO(b/245472831): Verify the component should snap to divider. + .isVisible(component) + .then() + .isInvisible(component, isOptional = true) + .then() + .isVisible(component) + } + } +} + +fun FlickerTestParameter.splitAppLayerBoundsBecomesInvisible( + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean +) { + assertLayers { + this.splitAppLayerBoundsSnapToDivider( + component, landscapePosLeft, portraitPosTop, endRotation) + .then() + .isVisible(component, true) + .then() + .isInvisible(component) } } fun FlickerTestParameter.splitAppLayerBoundsIsVisibleAtEnd( - rotation: Int, - component: FlickerComponentName, - splitLeftTop: Boolean + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean ) { assertLayersEnd { + splitAppLayerBoundsSnapToDivider(component, landscapePosLeft, portraitPosTop, endRotation) + } +} + +fun FlickerTestParameter.splitAppLayerBoundsKeepVisible( + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean +) { + assertLayers { + splitAppLayerBoundsSnapToDivider(component, landscapePosLeft, portraitPosTop, endRotation) + } +} + +fun FlickerTestParameter.splitAppLayerBoundsChanges( + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean +) { + assertLayers { + if (landscapePosLeft) { + this.splitAppLayerBoundsSnapToDivider( + component, landscapePosLeft, portraitPosTop, endRotation) + } else { + this.splitAppLayerBoundsSnapToDivider( + component, landscapePosLeft, portraitPosTop, endRotation) + .then() + .isInvisible(component) + .then() + .splitAppLayerBoundsSnapToDivider( + component, landscapePosLeft, portraitPosTop, endRotation) + } + } +} + +fun LayersTraceSubject.splitAppLayerBoundsSnapToDivider( + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean, + rotation: Int +): LayersTraceSubject { + return invoke("splitAppLayerBoundsSnapToDivider") { + it.splitAppLayerBoundsSnapToDivider(component, landscapePosLeft, portraitPosTop, rotation) + } +} + +fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( + component: IComponentMatcher, + landscapePosLeft: Boolean, + portraitPosTop: Boolean, + rotation: Int +): LayerTraceEntrySubject { + val displayBounds = WindowUtils.getDisplayBounds(rotation) + return invoke { val dividerRegion = layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region - visibleRegion(component).overlaps( - if (splitLeftTop) { - getSplitLeftTopRegion(dividerRegion, rotation) + visibleRegion(component).coversAtMost( + if (displayBounds.width > displayBounds.height) { + if (landscapePosLeft) { + Region.from( + 0, + 0, + (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, + displayBounds.bounds.bottom) + } else { + Region.from( + (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, + 0, + displayBounds.bounds.right, + displayBounds.bounds.bottom + ) + } } else { - getSplitRightBottomRegion(dividerRegion, rotation) + if (portraitPosTop) { + Region.from( + 0, + 0, + displayBounds.bounds.right, + (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2) + } else { + Region.from( + 0, + (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2, + displayBounds.bounds.right, + displayBounds.bounds.bottom + ) + } } ) } } fun FlickerTestParameter.appWindowBecomesVisible( - component: FlickerComponentName + component: IComponentMatcher ) { assertWm { this.isAppWindowInvisible(component) .then() + .notContains(component, isOptional = true) + .then() + .isAppWindowInvisible(component, isOptional = true) + .then() .isAppWindowVisible(component) } } +fun FlickerTestParameter.appWindowBecomesInvisible( + component: IComponentMatcher +) { + assertWm { + this.isAppWindowVisible(component) + .then() + .isAppWindowInvisible(component) + } +} + fun FlickerTestParameter.appWindowIsVisibleAtEnd( - component: FlickerComponentName + component: IComponentMatcher ) { assertWmEnd { this.isAppWindowVisible(component) } } +fun FlickerTestParameter.appWindowKeepVisible( + component: IComponentMatcher +) { + assertWm { + this.isAppWindowVisible(component) + } +} + fun FlickerTestParameter.dockedStackDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) @@ -151,7 +317,7 @@ fun FlickerTestParameter.dockedStackDividerNotExistsAtEnd() { fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( rotation: Int, - primaryComponent: FlickerComponentName + primaryComponent: IComponentMatcher ) { assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region @@ -162,7 +328,7 @@ fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd( rotation: Int, - primaryComponent: FlickerComponentName + primaryComponent: IComponentMatcher ) { assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region @@ -173,7 +339,7 @@ fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd( fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd( rotation: Int, - secondaryComponent: FlickerComponentName + secondaryComponent: IComponentMatcher ) { assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region @@ -184,7 +350,7 @@ fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd( fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisibleAtEnd( rotation: Int, - secondaryComponent: FlickerComponentName + secondaryComponent: IComponentMatcher ) { assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region @@ -222,27 +388,3 @@ fun getSecondaryRegion(dividerRegion: Region, rotation: Int): Region { ) } } - -fun getSplitLeftTopRegion(dividerRegion: Region, rotation: Int): Region { - val displayBounds = WindowUtils.getDisplayBounds(rotation) - return if (displayBounds.width > displayBounds.height) { - Region.from(0, 0, dividerRegion.bounds.left, displayBounds.bounds.bottom) - } else { - Region.from(0, 0, displayBounds.bounds.right, dividerRegion.bounds.top) - } -} - -fun getSplitRightBottomRegion(dividerRegion: Region, rotation: Int): Region { - val displayBounds = WindowUtils.getDisplayBounds(rotation) - return if (displayBounds.width > displayBounds.height) { - Region.from( - dividerRegion.bounds.right, 0, displayBounds.bounds.right, - displayBounds.bounds.bottom - ) - } else { - Region.from( - 0, dividerRegion.bounds.bottom, displayBounds.bounds.right, - displayBounds.bounds.bottom - ) - } -} 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/CommonConstants.kt index f56eb6e783aa..53dd8b04afeb 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/CommonConstants.kt @@ -17,9 +17,14 @@ @file:JvmName("CommonConstants") package com.android.wm.shell.flicker -import com.android.server.wm.traces.common.FlickerComponentName +import com.android.server.wm.traces.common.ComponentNameMatcher const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui" -val APP_PAIR_SPLIT_DIVIDER_COMPONENT = FlickerComponentName("", "AppPairSplitDivider#") -val DOCKED_STACK_DIVIDER_COMPONENT = FlickerComponentName("", "DockedStackDivider#") -val SPLIT_SCREEN_DIVIDER_COMPONENT = FlickerComponentName("", "StageCoordinatorSplitDivider#") +val APP_PAIR_SPLIT_DIVIDER_COMPONENT = ComponentNameMatcher("", "AppPairSplitDivider#") +val DOCKED_STACK_DIVIDER_COMPONENT = ComponentNameMatcher("", "DockedStackDivider#") +val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentNameMatcher("", "StageCoordinatorSplitDivider#") +val SPLIT_DECOR_MANAGER = ComponentNameMatcher("", "SplitDecorManager#") + +enum class Direction { + UP, DOWN, LEFT, RIGHT +} 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/MultiWindowUtils.kt new file mode 100644 index 000000000000..c045325f19c3 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/MultiWindowUtils.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.flicker + +import android.app.Instrumentation +import android.content.Context +import android.provider.Settings +import android.util.Log +import com.android.compatibility.common.util.SystemUtil +import java.io.IOException + +object MultiWindowUtils { + private fun executeShellCommand(instrumentation: Instrumentation, cmd: String) { + try { + SystemUtil.runShellCommand(instrumentation, cmd) + } catch (e: IOException) { + Log.e(MultiWindowUtils::class.simpleName, "executeShellCommand error! $e") + } + } + + fun getDevEnableNonResizableMultiWindow(context: Context): Int = + Settings.Global.getInt(context.contentResolver, + Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW) + + fun setDevEnableNonResizableMultiWindow(context: Context, configValue: Int) = + Settings.Global.putInt(context.contentResolver, + Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue) + + fun setSupportsNonResizableMultiWindow(instrumentation: Instrumentation, configValue: Int) = + executeShellCommand( + instrumentation, + createConfigSupportsNonResizableMultiWindowCommand(configValue)) + + fun resetMultiWindowConfig(instrumentation: Instrumentation) = + executeShellCommand(instrumentation, resetMultiWindowConfigCommand) + + private fun createConfigSupportsNonResizableMultiWindowCommand(configValue: Int): String = + "wm set-multi-window-config --supportsNonResizable $configValue" + + private const val resetMultiWindowConfigCommand: String = "wm reset-multi-window-config" +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt index 278ba9b0f4db..cbe085be8952 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt @@ -17,40 +17,38 @@ package com.android.wm.shell.flicker.bubble import android.app.INotificationManager -import android.app.Instrumentation import android.app.NotificationManager import android.content.Context +import android.content.pm.PackageManager import android.os.ServiceManager import android.view.Surface -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.Until import com.android.server.wm.flicker.Flicker -import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.LaunchBubbleHelper import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE -import com.android.wm.shell.flicker.helpers.LaunchBubbleHelper +import com.android.wm.shell.flicker.BaseTest import org.junit.runners.Parameterized /** * Base configurations for Bubble flicker tests */ -abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) { +abstract class BaseBubbleScreen( + testSpec: FlickerTestParameter +) : BaseTest(testSpec) { - protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() protected val context: Context = instrumentation.context protected val testApp = LaunchBubbleHelper(instrumentation) - protected val notifyManager = INotificationManager.Stub.asInterface( + private val notifyManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)) - protected val uid = context.packageManager.getApplicationInfo( - testApp.component.packageName, 0).uid - - protected abstract val transition: FlickerBuilder.() -> Unit + private val uid = context.packageManager.getApplicationInfo( + testApp.`package`, PackageManager.ApplicationInfoFlags.of(0)).uid @JvmOverloads protected open fun buildTransition( @@ -58,21 +56,17 @@ abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) { ): FlickerBuilder.() -> Unit { return { setup { - test { - notifyManager.setBubblesAllowed(testApp.component.packageName, - uid, NotificationManager.BUBBLE_PREFERENCE_ALL) - testApp.launchViaIntent(wmHelper) - waitAndGetAddBubbleBtn() - waitAndGetCancelAllBtn() - } + notifyManager.setBubblesAllowed(testApp.`package`, + uid, NotificationManager.BUBBLE_PREFERENCE_ALL) + testApp.launchViaIntent(wmHelper) + waitAndGetAddBubbleBtn() + waitAndGetCancelAllBtn() } teardown { - test { - notifyManager.setBubblesAllowed(testApp.component.packageName, - uid, NotificationManager.BUBBLE_PREFERENCE_NONE) - testApp.exit() - } + notifyManager.setBubblesAllowed(testApp.`package`, + uid, NotificationManager.BUBBLE_PREFERENCE_NONE) + testApp.exit() } extraSpec(this) @@ -84,20 +78,12 @@ abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) { protected fun Flicker.waitAndGetCancelAllBtn(): UiObject2? = device.wait(Until.findObject( By.text("Cancel All Bubble")), FIND_OBJECT_TIMEOUT) - @FlickerBuilderProvider - fun buildFlicker(): FlickerBuilder { - return FlickerBuilder(instrumentation).apply { - transition(this) - } - } - companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } const val FIND_OBJECT_TIMEOUT = 2000L diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt index b137e92881a5..ac4de4780746 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt @@ -18,6 +18,7 @@ package com.android.wm.shell.flicker.bubble import android.content.Context import android.graphics.Point +import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.util.DisplayMetrics import android.view.WindowManager @@ -28,8 +29,8 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder -import org.junit.runner.RunWith import org.junit.Test +import org.junit.runner.RunWith import org.junit.runners.Parameterized /** @@ -49,19 +50,21 @@ open class DismissBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScree private val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager private val displaySize = DisplayMetrics() + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = buildTransition { setup { - eachRun { - val addBubbleBtn = waitAndGetAddBubbleBtn() - addBubbleBtn?.click() ?: error("Add Bubble not found") - } + val addBubbleBtn = waitAndGetAddBubbleBtn() + addBubbleBtn?.click() ?: error("Add Bubble not found") } transitions { - wm.run { wm.getDefaultDisplay().getMetrics(displaySize) } + wm.run { wm.defaultDisplay.getMetrics(displaySize) } val dist = Point((displaySize.widthPixels / 2), displaySize.heightPixels) - val showBubble = device.wait(Until.findObject( - By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT) + val showBubble = device.wait( + Until.findObject( + By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME) + ), FIND_OBJECT_TIMEOUT + ) showBubble?.run { drag(dist, 1000) } ?: error("Show bubble not found") } } @@ -70,7 +73,25 @@ open class DismissBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScree @Test open fun testAppIsAlwaysVisible() { testSpec.assertLayers { - this.isVisible(testApp.component) + this.isVisible(testApp) } } + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt index f288b0a24d9d..7807854ac70a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt @@ -24,8 +24,8 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder -import org.junit.runner.RunWith import org.junit.Test +import org.junit.runner.RunWith import org.junit.runners.Parameterized /** @@ -44,17 +44,19 @@ import org.junit.runners.Parameterized @Group4 open class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) { + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = buildTransition { setup { - test { - val addBubbleBtn = waitAndGetAddBubbleBtn() - addBubbleBtn?.click() ?: error("Add Bubble not found") - } + val addBubbleBtn = waitAndGetAddBubbleBtn() + addBubbleBtn?.click() ?: error("Add Bubble not found") } transitions { - val showBubble = device.wait(Until.findObject( - By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT) + val showBubble = device.wait( + Until.findObject( + By.res("com.android.systemui", "bubble_view") + ), FIND_OBJECT_TIMEOUT + ) showBubble?.run { showBubble.click() } ?: error("Bubble notify not found") } } @@ -63,7 +65,7 @@ open class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen @Test open fun testAppIsAlwaysVisible() { testSpec.assertLayers { - this.isVisible(testApp.component) + this.isVisible(testApp) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt index 684e5cad0e67..49681e140cef 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt @@ -16,10 +16,10 @@ package com.android.wm.shell.flicker.bubble -import android.platform.test.annotations.Presubmit +import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.Postsubmit import android.view.WindowInsets import android.view.WindowManager -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By import androidx.test.uiautomator.Until @@ -27,10 +27,8 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled -import org.junit.Assume -import org.junit.runner.RunWith import org.junit.Test +import org.junit.runner.RunWith import org.junit.runners.Parameterized /** @@ -47,36 +45,43 @@ import org.junit.runners.Parameterized @Group4 class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) { + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = buildTransition { setup { - eachRun { - val addBubbleBtn = waitAndGetAddBubbleBtn() - addBubbleBtn?.click() ?: error("Bubble widget not found") - device.sleep() - wmHelper.waitFor("noAppWindowsOnTop") { - it.wmState.topVisibleAppWindow.isEmpty() - } - device.wakeUp() - } + val addBubbleBtn = waitAndGetAddBubbleBtn() + addBubbleBtn?.click() ?: error("Bubble widget not found") + device.sleep() + wmHelper.StateSyncBuilder() + .withoutTopVisibleAppWindows() + .waitForAndVerify() + device.wakeUp() } transitions { // Swipe & wait for the notification shade to expand so all can be seen val wm = context.getSystemService(WindowManager::class.java) - val metricInsets = wm.getCurrentWindowMetrics().windowInsets + ?: error("Unable to obtain WM service") + val metricInsets = wm.currentWindowMetrics.windowInsets val insets = metricInsets.getInsetsIgnoringVisibility( - WindowInsets.Type.statusBars() - or WindowInsets.Type.displayCutout()) - device.swipe(100, insets.top + 100, 100, device.getDisplayHeight() / 2, 4) + WindowInsets.Type.statusBars() + or WindowInsets.Type.displayCutout() + ) + device.swipe(100, insets.top + 100, 100, device.displayHeight / 2, 4) device.waitForIdle(2000) instrumentation.uiAutomation.syncInputTransactions() - val notification = device.wait(Until.findObject( - By.text("BubbleChat")), FIND_OBJECT_TIMEOUT) + val notification = device.wait( + Until.findObject( + By.text("BubbleChat") + ), FIND_OBJECT_TIMEOUT + ) notification?.click() ?: error("Notification not found") instrumentation.uiAutomation.syncInputTransactions() - val showBubble = device.wait(Until.findObject( - By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT) + val showBubble = device.wait( + Until.findObject( + By.res("com.android.systemui", "bubble_view") + ), FIND_OBJECT_TIMEOUT + ) showBubble?.click() ?: error("Bubble notify not found") instrumentation.uiAutomation.syncInputTransactions() val cancelAllBtn = waitAndGetCancelAllBtn() @@ -84,21 +89,71 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr } } - @Presubmit + @FlakyTest(bugId = 242088970) @Test fun testAppIsVisibleAtEnd() { - Assume.assumeFalse(isShellTransitionsEnabled) testSpec.assertLayersEnd { - this.isVisible(testApp.component) + this.isVisible(testApp) } } + /** {@inheritDoc} */ @FlakyTest @Test - fun testAppIsVisibleAtEnd_ShellTransit() { - Assume.assumeTrue(isShellTransitionsEnabled) - testSpec.assertLayersEnd { - this.isVisible(testApp.component) - } - } + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 206753786) + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 206753786) + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 206753786) + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt index 0bb4d398bff4..9a6fd1103766 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt @@ -16,8 +16,9 @@ package com.android.wm.shell.flicker.bubble -import android.platform.test.annotations.Presubmit import android.platform.test.annotations.RequiresDevice +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group4 @@ -41,19 +42,25 @@ import org.junit.runners.Parameterized @Group4 open class LaunchBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) { + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = buildTransition { transitions { val addBubbleBtn = waitAndGetAddBubbleBtn() addBubbleBtn?.click() ?: error("Bubble widget not found") + + device.wait( + Until.findObjects( + By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME) + ), FIND_OBJECT_TIMEOUT + ) ?: error("No bubbles found") } } - @Presubmit @Test open fun testAppIsAlwaysVisible() { testSpec.assertLayers { - this.isVisible(testApp.component) + this.isVisible(testApp) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt index 8d1e315e2d5e..fac0f73e9e10 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt @@ -20,6 +20,7 @@ import android.os.SystemClock import android.platform.test.annotations.Presubmit import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.Until import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -28,8 +29,8 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled import org.junit.Assume import org.junit.Before -import org.junit.runner.RunWith import org.junit.Test +import org.junit.runner.RunWith import org.junit.runners.Parameterized /** @@ -51,25 +52,31 @@ open class MultiBubblesScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen Assume.assumeFalse(isShellTransitionsEnabled) } + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = buildTransition { setup { - test { - for (i in 1..3) { - val addBubbleBtn = waitAndGetAddBubbleBtn() - addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Add Bubble not found") - } - val showBubble = device.wait(Until.findObject( - By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT) - showBubble?.run { showBubble.click() } ?: error("Show bubble not found") + for (i in 1..3) { + val addBubbleBtn = waitAndGetAddBubbleBtn() ?: error("Add Bubble not found") + addBubbleBtn.click() SystemClock.sleep(1000) } + val showBubble = device.wait( + Until.findObject( + By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME) + ), FIND_OBJECT_TIMEOUT + ) ?: error("Show bubble not found") + showBubble.click() + SystemClock.sleep(1000) } transitions { - val bubbles = device.wait(Until.findObjects( - By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT) + val bubbles: List<UiObject2> = device.wait( + Until.findObjects( + By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME) + ), FIND_OBJECT_TIMEOUT + ) ?: error("No bubbles found") for (entry in bubbles) { - entry?.run { entry.click() } ?: error("Bubble not found") + entry.click() SystemClock.sleep(1000) } } @@ -79,7 +86,7 @@ open class MultiBubblesScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen @Test open fun testAppIsAlwaysVisible() { testSpec.assertLayers { - this.isVisible(testApp.component) + this.isVisible(testApp) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreenShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreenShellTransit.kt index ddebb6fed636..971097deed06 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreenShellTransit.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreenShellTransit.kt @@ -16,7 +16,7 @@ package com.android.wm.shell.flicker.bubble -import androidx.test.filters.FlakyTest +import android.platform.test.annotations.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt deleted file mode 100644 index 41cd31aabf05..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import com.android.server.wm.flicker.Flicker -import com.android.server.wm.flicker.helpers.WindowUtils -import com.android.server.wm.traces.common.FlickerComponentName -import com.android.server.wm.traces.common.region.Region - -class AppPairsHelper( - instrumentation: Instrumentation, - activityLabel: String, - component: FlickerComponentName -) : BaseAppHelper(instrumentation, activityLabel, component) { - fun getPrimaryBounds(dividerBounds: Region): Region { - val primaryAppBounds = Region.from(0, 0, dividerBounds.bounds.right, - dividerBounds.bounds.bottom + WindowUtils.dockedStackDividerInset) - return primaryAppBounds - } - - fun getSecondaryBounds(dividerBounds: Region): Region { - val displayBounds = WindowUtils.displayBounds - val secondaryAppBounds = Region.from(0, - dividerBounds.bounds.bottom - WindowUtils.dockedStackDividerInset, - displayBounds.right, displayBounds.bottom - WindowUtils.navigationBarFrameHeight) - return secondaryAppBounds - } - - companion object { - const val TEST_REPETITIONS = 1 - const val TIMEOUT_MS = 3_000L - - fun Flicker.waitAppsShown(app1: SplitScreenHelper?, app2: SplitScreenHelper?) { - wmHelper.waitFor("primaryAndSecondaryAppsVisible") { dump -> - val primaryAppVisible = app1?.let { - dump.wmState.isWindowSurfaceShown(app1.defaultWindowName) - } ?: false - val secondaryAppVisible = app2?.let { - dump.wmState.isWindowSurfaceShown(app2.defaultWindowName) - } ?: false - primaryAppVisible && secondaryAppVisible - } - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt deleted file mode 100644 index 3dd9e0572947..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import android.content.pm.PackageManager.FEATURE_LEANBACK -import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY -import android.os.SystemProperties -import android.support.test.launcherhelper.LauncherStrategyFactory -import android.util.Log -import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiObject2 -import androidx.test.uiautomator.Until -import com.android.compatibility.common.util.SystemUtil -import com.android.server.wm.flicker.helpers.StandardAppHelper -import com.android.server.wm.traces.common.FlickerComponentName -import java.io.IOException - -abstract class BaseAppHelper( - instrumentation: Instrumentation, - launcherName: String, - component: FlickerComponentName -) : StandardAppHelper( - instrumentation, - launcherName, - component, - LauncherStrategyFactory.getInstance(instrumentation).launcherStrategy -) { - private val appSelector = By.pkg(component.packageName).depth(0) - - protected val isTelevision: Boolean - get() = context.packageManager.run { - hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY) - } - - val defaultWindowName: String - get() = component.toWindowName() - - val ui: UiObject2? - get() = uiDevice.findObject(appSelector) - - fun waitUntilClosed(): Boolean { - return uiDevice.wait(Until.gone(appSelector), APP_CLOSE_WAIT_TIME_MS) - } - - companion object { - private const val APP_CLOSE_WAIT_TIME_MS = 3_000L - - fun isShellTransitionsEnabled() = - SystemProperties.getBoolean("persist.wm.debug.shell_transit", false) - - fun executeShellCommand(instrumentation: Instrumentation, cmd: String) { - try { - SystemUtil.runShellCommand(instrumentation, cmd) - } catch (e: IOException) { - Log.e("BaseAppHelper", "executeShellCommand error! $e") - } - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FixedAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FixedAppHelper.kt deleted file mode 100644 index 471e010cf560..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FixedAppHelper.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import com.android.server.wm.traces.parser.toFlickerComponent -import com.android.wm.shell.flicker.testapp.Components - -class FixedAppHelper(instrumentation: Instrumentation) : BaseAppHelper( - instrumentation, - Components.FixedActivity.LABEL, - Components.FixedActivity.COMPONENT.toFlickerComponent() -)
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt deleted file mode 100644 index cc5b9f9eb26d..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.Until -import com.android.server.wm.flicker.helpers.FIND_TIMEOUT -import com.android.server.wm.traces.parser.toFlickerComponent -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper -import com.android.wm.shell.flicker.testapp.Components - -open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( - instrumentation, - Components.ImeActivity.LABEL, - Components.ImeActivity.COMPONENT.toFlickerComponent() -) { - /** - * Opens the IME and wait for it to be displayed - * - * @param wmHelper Helper used to wait for WindowManager states - */ - @JvmOverloads - open fun openIME(wmHelper: WindowManagerStateHelper? = null) { - if (!isTelevision) { - val editText = uiDevice.wait( - Until.findObject(By.res(getPackage(), "plain_text_input")), - FIND_TIMEOUT) - - require(editText != null) { - "Text field not found, this usually happens when the device " + - "was left in an unknown state (e.g. in split screen)" - } - editText.click() - waitAndAssertIMEShown(uiDevice, wmHelper) - } else { - // If we do the same thing as above - editText.click() - on TV, that's going to force TV - // into the touch mode. We really don't want that. - launchViaIntent(action = Components.ImeActivity.ACTION_OPEN_IME) - } - } - - protected fun waitAndAssertIMEShown( - device: UiDevice, - wmHelper: WindowManagerStateHelper? = null - ) { - if (wmHelper == null) { - device.waitForIdle() - } else { - wmHelper.waitImeShown() - } - } - - /** - * Opens the IME and wait for it to be gone - * - * @param wmHelper Helper used to wait for WindowManager states - */ - @JvmOverloads - open fun closeIME(wmHelper: WindowManagerStateHelper? = null) { - if (!isTelevision) { - uiDevice.pressBack() - // Using only the AccessibilityInfo it is not possible to identify if the IME is active - if (wmHelper == null) { - uiDevice.waitForIdle() - } else { - wmHelper.waitImeGone() - } - } else { - // While pressing the back button should close the IME on TV as well, it may also lead - // to the app closing. So let's instead just ask the app to close the IME. - launchViaIntent(action = Components.ImeActivity.ACTION_CLOSE_IME) - } - } -}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/LaunchBubbleHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/LaunchBubbleHelper.kt deleted file mode 100644 index 6695c17ed514..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/LaunchBubbleHelper.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import com.android.server.wm.traces.parser.toFlickerComponent -import com.android.wm.shell.flicker.testapp.Components - -class LaunchBubbleHelper(instrumentation: Instrumentation) : BaseAppHelper( - instrumentation, - Components.LaunchBubbleActivity.LABEL, - Components.LaunchBubbleActivity.COMPONENT.toFlickerComponent() -) { - - companion object { - const val TEST_REPETITIONS = 1 - const val TIMEOUT_MS = 3_000L - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt deleted file mode 100644 index 12ccbafce651..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import android.content.Context -import android.provider.Settings -import com.android.server.wm.traces.common.FlickerComponentName - -class MultiWindowHelper( - instrumentation: Instrumentation, - activityLabel: String, - componentsInfo: FlickerComponentName -) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) { - - companion object { - fun getDevEnableNonResizableMultiWindow(context: Context): Int = - Settings.Global.getInt(context.contentResolver, - Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW) - - fun setDevEnableNonResizableMultiWindow(context: Context, configValue: Int) = - Settings.Global.putInt(context.contentResolver, - Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue) - - fun setSupportsNonResizableMultiWindow(instrumentation: Instrumentation, configValue: Int) = - executeShellCommand( - instrumentation, - createConfigSupportsNonResizableMultiWindowCommand(configValue)) - - fun resetMultiWindowConfig(instrumentation: Instrumentation) = - executeShellCommand(instrumentation, resetMultiWindowConfigCommand) - - private fun createConfigSupportsNonResizableMultiWindowCommand(configValue: Int): String = - "wm set-multi-window-config --supportsNonResizable $configValue" - - private const val resetMultiWindowConfigCommand: String = "wm reset-multi-window-config" - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt deleted file mode 100644 index 8157a4e453af..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import android.media.session.MediaController -import android.media.session.MediaSessionManager -import android.os.SystemClock -import androidx.test.uiautomator.By -import androidx.test.uiautomator.BySelector -import androidx.test.uiautomator.Until -import com.android.server.wm.flicker.helpers.FIND_TIMEOUT -import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE -import com.android.server.wm.traces.common.Rect -import com.android.server.wm.traces.parser.toFlickerComponent -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper -import com.android.wm.shell.flicker.pip.tv.closeTvPipWindow -import com.android.wm.shell.flicker.pip.tv.isFocusedOrHasFocusedChild -import com.android.wm.shell.flicker.testapp.Components - -class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( - instrumentation, - Components.PipActivity.LABEL, - Components.PipActivity.COMPONENT.toFlickerComponent() -) { - private val mediaSessionManager: MediaSessionManager - get() = context.getSystemService(MediaSessionManager::class.java) - ?: error("Could not get MediaSessionManager") - - private val mediaController: MediaController? - get() = mediaSessionManager.getActiveSessions(null).firstOrNull { - it.packageName == component.packageName - } - - fun clickObject(resId: String) { - val selector = By.res(component.packageName, resId) - val obj = uiDevice.findObject(selector) ?: error("Could not find `$resId` object") - - if (!isTelevision) { - obj.click() - } else { - focusOnObject(selector) || error("Could not focus on `$resId` object") - uiDevice.pressDPadCenter() - } - } - - /** - * Launches the app through an intent instead of interacting with the launcher and waits - * until the app window is in PIP mode - */ - @JvmOverloads - fun launchViaIntentAndWaitForPip( - wmHelper: WindowManagerStateHelper, - expectedWindowName: String = "", - action: String? = null, - stringExtras: Map<String, String> - ) { - launchViaIntentAndWaitShown( - wmHelper, expectedWindowName, action, stringExtras, - waitConditions = arrayOf(WindowManagerStateHelper.pipShownCondition) - ) - } - - /** - * Expand the PIP window back to full screen via intent and wait until the app is visible - */ - fun exitPipToFullScreenViaIntent(wmHelper: WindowManagerStateHelper) = - launchViaIntentAndWaitShown(wmHelper) - - private fun focusOnObject(selector: BySelector): Boolean { - // We expect all the focusable UI elements to be arranged in a way so that it is possible - // to "cycle" over all them by clicking the D-Pad DOWN button, going back up to "the top" - // from "the bottom". - repeat(FOCUS_ATTEMPTS) { - uiDevice.findObject(selector)?.apply { if (isFocusedOrHasFocusedChild) return true } - ?: error("The object we try to focus on is gone.") - - uiDevice.pressDPadDown() - uiDevice.waitForIdle() - } - return false - } - - @JvmOverloads - fun clickEnterPipButton(wmHelper: WindowManagerStateHelper? = null) { - clickObject(ENTER_PIP_BUTTON_ID) - - // Wait on WMHelper or simply wait for 3 seconds - wmHelper?.waitPipShown() ?: SystemClock.sleep(3_000) - // when entering pip, the dismiss button is visible at the start. to ensure the pip - // animation is complete, wait until the pip dismiss button is no longer visible. - // b/176822698: dismiss-only state will be removed in the future - uiDevice.wait(Until.gone(By.res(SYSTEMUI_PACKAGE, "dismiss")), FIND_TIMEOUT) - } - - fun enableEnterPipOnUserLeaveHint() { - clickObject(ENTER_PIP_ON_USER_LEAVE_HINT) - } - - fun enableAutoEnterForPipActivity() { - clickObject(ENTER_PIP_AUTOENTER) - } - - fun clickStartMediaSessionButton() { - clickObject(MEDIA_SESSION_START_RADIO_BUTTON_ID) - } - - fun checkWithCustomActionsCheckbox() = uiDevice - .findObject(By.res(component.packageName, WITH_CUSTOM_ACTIONS_BUTTON_ID)) - ?.takeIf { it.isCheckable } - ?.apply { if (!isChecked) clickObject(WITH_CUSTOM_ACTIONS_BUTTON_ID) } - ?: error("'With custom actions' checkbox not found") - - fun pauseMedia() = mediaController?.transportControls?.pause() - ?: error("No active media session found") - - fun stopMedia() = mediaController?.transportControls?.stop() - ?: error("No active media session found") - - @Deprecated( - "Use PipAppHelper.closePipWindow(wmHelper) instead", - ReplaceWith("closePipWindow(wmHelper)") - ) - fun closePipWindow() { - if (isTelevision) { - uiDevice.closeTvPipWindow() - } else { - closePipWindow(WindowManagerStateHelper(mInstrumentation)) - } - } - - private fun getWindowRect(wmHelper: WindowManagerStateHelper): Rect { - val windowRegion = wmHelper.getWindowRegion(component) - require(!windowRegion.isEmpty) { - "Unable to find a PIP window in the current state" - } - return windowRegion.bounds - } - - /** - * Taps the pip window and dismisses it by clicking on the X button. - */ - fun closePipWindow(wmHelper: WindowManagerStateHelper) { - if (isTelevision) { - uiDevice.closeTvPipWindow() - } else { - val windowRect = getWindowRect(wmHelper) - uiDevice.click(windowRect.centerX(), windowRect.centerY()) - // search and interact with the dismiss button - val dismissSelector = By.res(SYSTEMUI_PACKAGE, "dismiss") - uiDevice.wait(Until.hasObject(dismissSelector), FIND_TIMEOUT) - val dismissPipObject = uiDevice.findObject(dismissSelector) - ?: error("PIP window dismiss button not found") - val dismissButtonBounds = dismissPipObject.visibleBounds - uiDevice.click(dismissButtonBounds.centerX(), dismissButtonBounds.centerY()) - } - - // Wait for animation to complete. - wmHelper.waitPipGone() - wmHelper.waitForHomeActivityVisible() - } - - /** - * Close the pip window by pressing the expand button - */ - fun expandPipWindowToApp(wmHelper: WindowManagerStateHelper) { - val windowRect = getWindowRect(wmHelper) - uiDevice.click(windowRect.centerX(), windowRect.centerY()) - // search and interact with the expand button - val expandSelector = By.res(SYSTEMUI_PACKAGE, "expand_button") - uiDevice.wait(Until.hasObject(expandSelector), FIND_TIMEOUT) - val expandPipObject = uiDevice.findObject(expandSelector) - ?: error("PIP window expand button not found") - val expandButtonBounds = expandPipObject.visibleBounds - uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY()) - wmHelper.waitPipGone() - wmHelper.waitForAppTransitionIdle() - } - - /** - * Double click on the PIP window to expand it - */ - fun doubleClickPipWindow(wmHelper: WindowManagerStateHelper) { - val windowRect = getWindowRect(wmHelper) - uiDevice.click(windowRect.centerX(), windowRect.centerY()) - uiDevice.click(windowRect.centerX(), windowRect.centerY()) - wmHelper.waitForAppTransitionIdle() - } - - companion object { - private const val FOCUS_ATTEMPTS = 20 - private const val ENTER_PIP_BUTTON_ID = "enter_pip" - private const val WITH_CUSTOM_ACTIONS_BUTTON_ID = "with_custom_actions" - private const val MEDIA_SESSION_START_RADIO_BUTTON_ID = "media_session_start" - private const val ENTER_PIP_ON_USER_LEAVE_HINT = "enter_pip_on_leave_manual" - private const val ENTER_PIP_AUTOENTER = "enter_pip_on_leave_autoenter" - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SimpleAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SimpleAppHelper.kt deleted file mode 100644 index 4d0fbc4a0e38..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SimpleAppHelper.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import com.android.server.wm.traces.parser.toFlickerComponent -import com.android.wm.shell.flicker.testapp.Components - -class SimpleAppHelper(instrumentation: Instrumentation) : BaseAppHelper( - instrumentation, - Components.SimpleActivity.LABEL, - Components.SimpleActivity.COMPONENT.toFlickerComponent() -)
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt deleted file mode 100644 index 49eca63a23ec..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.helpers - -import android.app.Instrumentation -import android.graphics.Point -import android.os.SystemClock -import android.view.InputDevice -import android.view.MotionEvent -import androidx.test.uiautomator.By -import androidx.test.uiautomator.BySelector -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.Until -import com.android.launcher3.tapl.LauncherInstrumentation -import com.android.server.wm.traces.common.FlickerComponentName -import com.android.server.wm.traces.parser.toFlickerComponent -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper -import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME -import com.android.wm.shell.flicker.testapp.Components -import org.junit.Assert - -class SplitScreenHelper( - instrumentation: Instrumentation, - activityLabel: String, - componentsInfo: FlickerComponentName -) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) { - - companion object { - const val TEST_REPETITIONS = 1 - const val TIMEOUT_MS = 3_000L - const val DRAG_DURATION_MS = 1_000L - const val NOTIFICATION_SCROLLER = "notification_stack_scroller" - const val GESTURE_STEP_MS = 16L - - private val notificationScrollerSelector: BySelector - get() = By.res(SYSTEM_UI_PACKAGE_NAME, NOTIFICATION_SCROLLER) - private val notificationContentSelector: BySelector - get() = By.text("Notification content") - - fun getPrimary(instrumentation: Instrumentation): SplitScreenHelper = - SplitScreenHelper( - instrumentation, - Components.SplitScreenActivity.LABEL, - Components.SplitScreenActivity.COMPONENT.toFlickerComponent() - ) - - fun getSecondary(instrumentation: Instrumentation): SplitScreenHelper = - SplitScreenHelper( - instrumentation, - Components.SplitScreenSecondaryActivity.LABEL, - Components.SplitScreenSecondaryActivity.COMPONENT.toFlickerComponent() - ) - - fun getNonResizeable(instrumentation: Instrumentation): SplitScreenHelper = - SplitScreenHelper( - instrumentation, - Components.NonResizeableActivity.LABEL, - Components.NonResizeableActivity.COMPONENT.toFlickerComponent() - ) - - fun getSendNotification(instrumentation: Instrumentation): SplitScreenHelper = - SplitScreenHelper( - instrumentation, - Components.SendNotificationActivity.LABEL, - Components.SendNotificationActivity.COMPONENT.toFlickerComponent() - ) - - 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, 20 /* steps */ - ) - SystemClock.sleep(TIMEOUT_MS) - - // Find the target notification - val notificationScroller = device.wait( - Until.findObject(notificationScrollerSelector), TIMEOUT_MS - ) - 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 - var dragStart = notificationContent.visibleCenter - var dragMiddle = Point(dragStart.x + 50, dragStart.y) - var 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( - taplInstrumentation: LauncherInstrumentation, - appName: String - ) { - taplInstrumentation.workspace - .deleteAppIcon(taplInstrumentation.workspace.getHotseatAppIcon(0)) - val allApps = taplInstrumentation.workspace.switchToAllApps() - allApps.freeze() - try { - val appIconSrc = allApps.getAppIcon(appName) - Assert.assertNotNull("Unable to find app icon", appIconSrc) - val appIconDest = appIconSrc.dragToHotseat(0) - Assert.assertNotNull("Unable to drag app icon on hotseat", appIconDest) - } finally { - allApps.unfreeze() - } - } - } -} 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 ce624f2b5bbe..9684bb32f48a 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 @@ -17,12 +17,17 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.Presubmit +import android.view.Surface import androidx.test.filters.RequiresDevice -import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule +import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome import org.junit.Assume import org.junit.FixMethodOrder import org.junit.Test @@ -54,35 +59,35 @@ import org.junit.runners.Parameterized @FlakyTest(bugId = 238367575) @Group3 class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(testSpec) { - protected val taplInstrumentation = LauncherInstrumentation() /** * Defines the transition used to run the test */ override val transition: FlickerBuilder.() -> Unit get() = { - setupAndTeardown(this) setup { - eachRun { - pipApp.launchViaIntent(wmHelper) - pipApp.enableAutoEnterForPipActivity() - } + removeAllTasksButHome() + device.wakeUpAndGoToHomeScreen() + pipApp.launchViaIntent(wmHelper) + pipApp.enableAutoEnterForPipActivity() } teardown { - eachRun { - // close gracefully so that onActivityUnpinned() can be called before force exit - pipApp.closePipWindow(wmHelper) - pipApp.exit(wmHelper) - } + // close gracefully so that onActivityUnpinned() can be called before force exit + pipApp.closePipWindow(wmHelper) + + setRotation(Surface.ROTATION_0) + RemoveAllTasksButHomeRule.removeAllTasksButHome() + pipApp.exit(wmHelper) } transitions { - taplInstrumentation.goHome() + tapl.goHome() } } + @FlakyTest + @Test override fun pipLayerReduces() { - val layerName = pipApp.component.toLayerName() testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } pipLayerList.zipWithNext { previous, current -> current.visibleRegion.notBiggerThan(previous.visibleRegion.region) } @@ -92,13 +97,13 @@ class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest( /** * Checks that [pipApp] window is animated towards default position in right bottom corner */ + @Presubmit @Test fun pipLayerMovesTowardsRightBottomCorner() { // in gestural nav the swipe makes PiP first go upwards Assume.assumeFalse(testSpec.isGesturalNavigation) - val layerName = pipApp.component.toLayerName() testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } // Pip animates towards the right bottom corner, but because it is being resized at the // same time, it is possible it shrinks first quickly below the default position and get // moved up after that in just few last frames @@ -108,6 +113,8 @@ class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest( } } + @Presubmit + @Test override fun focusChanges() { // in gestural nav the focus goes to different activity on swipe up Assume.assumeFalse(testSpec.isGesturalNavigation) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/CommonAssertions.kt deleted file mode 100644 index f9b08000290f..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/CommonAssertions.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:JvmName("CommonAssertions") -package com.android.wm.shell.flicker.pip - -internal const val PIP_WINDOW_COMPONENT = "PipMenuActivity" 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 953f59a1f70b..59f7ecf4d100 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 @@ -16,14 +16,21 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.Presubmit +import android.view.Surface import androidx.test.filters.RequiresDevice -import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule import org.junit.Assume import org.junit.FixMethodOrder +import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized @@ -51,60 +58,81 @@ import org.junit.runners.Parameterized @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group3 class EnterPipOnUserLeaveHintTest(testSpec: FlickerTestParameter) : EnterPipTest(testSpec) { - protected val taplInstrumentation = LauncherInstrumentation() /** * Defines the transition used to run the test */ override val transition: FlickerBuilder.() -> Unit get() = { - setupAndTeardown(this) setup { - eachRun { - pipApp.launchViaIntent(wmHelper) - pipApp.enableEnterPipOnUserLeaveHint() - } + RemoveAllTasksButHomeRule.removeAllTasksButHome() + device.wakeUpAndGoToHomeScreen() + device.wakeUpAndGoToHomeScreen() + pipApp.launchViaIntent(wmHelper) + pipApp.enableEnterPipOnUserLeaveHint() } teardown { - eachRun { - pipApp.exit(wmHelper) - } + setRotation(Surface.ROTATION_0) + RemoveAllTasksButHomeRule.removeAllTasksButHome() + pipApp.exit(wmHelper) } transitions { - taplInstrumentation.goHome() + tapl.goHome() } } + @Presubmit + @Test override fun pipAppLayerAlwaysVisible() { if (!testSpec.isGesturalNavigation) super.pipAppLayerAlwaysVisible() else { // pip layer in gesture nav will disappear during transition testSpec.assertLayers { - this.isVisible(pipApp.component) - .then().isInvisible(pipApp.component) - .then().isVisible(pipApp.component) + this.isVisible(pipApp) + .then().isInvisible(pipApp) + .then().isVisible(pipApp) } } } + @Presubmit + @Test override fun pipLayerReduces() { // in gestural nav the pip enters through alpha animation Assume.assumeFalse(testSpec.isGesturalNavigation) super.pipLayerReduces() } + @Presubmit + @Test override fun focusChanges() { // in gestural nav the focus goes to different activity on swipe up Assume.assumeFalse(testSpec.isGesturalNavigation) super.focusChanges() } + @Presubmit + @Test + override fun entireScreenCovered() { + Assume.assumeFalse(isShellTransitionsEnabled) + super.entireScreenCovered() + } + + @FlakyTest(bugId = 227313015) + @Test + fun entireScreenCovered_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + super.entireScreenCovered() + } + + @Presubmit + @Test override fun pipLayerRemainInsideVisibleBounds() { if (!testSpec.isGesturalNavigation) super.pipLayerRemainInsideVisibleBounds() else { // pip layer in gesture nav will disappear during transition testSpec.assertLayersStart { - this.visibleRegion(pipApp.component).coversAtMost(displayBounds) + this.visibleRegion(pipApp).coversAtMost(displayBounds) } testSpec.assertLayersEnd { - this.visibleRegion(pipApp.component).coversAtMost(displayBounds) + this.visibleRegion(pipApp).coversAtMost(displayBounds) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index 61ac49835185..c9e38e4231b6 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -16,15 +16,19 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import android.view.Surface import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory -import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule +import com.android.server.wm.traces.common.ComponentNameMatcher import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -55,21 +59,18 @@ import org.junit.runners.Parameterized @Group3 open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { - /** - * Defines the transition used to run the test - */ + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = { - setupAndTeardown(this) setup { - eachRun { - pipApp.launchViaIntent(wmHelper) - } + RemoveAllTasksButHomeRule.removeAllTasksButHome() + device.wakeUpAndGoToHomeScreen() + pipApp.launchViaIntent(wmHelper) } teardown { - eachRun { - pipApp.exit(wmHelper) - } + setRotation(Surface.ROTATION_0) + RemoveAllTasksButHomeRule.removeAllTasksButHome() + pipApp.exit(wmHelper) } transitions { pipApp.clickEnterPipButton(wmHelper) @@ -81,20 +82,20 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec */ @Presubmit @Test - fun pipAppWindowAlwaysVisible() { + open fun pipAppWindowAlwaysVisible() { testSpec.assertWm { - this.isAppWindowVisible(pipApp.component) + this.isAppWindowVisible(pipApp) } } /** * Checks [pipApp] layer remains visible throughout the animation */ - @Presubmit + @FlakyTest(bugId = 239807171) @Test open fun pipAppLayerAlwaysVisible() { testSpec.assertLayers { - this.isVisible(pipApp.component) + this.isVisible(pipApp) } } @@ -105,7 +106,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec @Presubmit @Test fun pipWindowRemainInsideVisibleBounds() { - testSpec.assertWmVisibleRegion(pipApp.component) { + testSpec.assertWmVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -114,10 +115,10 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec * Checks that the pip app layer remains inside the display bounds throughout the whole * animation */ - @Presubmit + @FlakyTest(bugId = 239807171) @Test open fun pipLayerRemainInsideVisibleBounds() { - testSpec.assertLayersVisibleRegion(pipApp.component) { + testSpec.assertLayersVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -128,9 +129,8 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec @Presubmit @Test open fun pipLayerReduces() { - val layerName = pipApp.component.toLayerName() testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } pipLayerList.zipWithNext { previous, current -> current.visibleRegion.notBiggerThan(previous.visibleRegion.region) } @@ -144,22 +144,22 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec @Test fun pipWindowBecomesPinned() { testSpec.assertWm { - invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp.component) } + invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp) } .then() - .invoke("pipWindowIsPinned") { it.isPinned(pipApp.component) } + .invoke("pipWindowIsPinned") { it.isPinned(pipApp) } } } /** - * Checks [LAUNCHER_COMPONENT] layer remains visible throughout the animation + * Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation */ @Presubmit @Test fun launcherLayerBecomesVisible() { testSpec.assertLayers { - isInvisible(LAUNCHER_COMPONENT) + isInvisible(ComponentNameMatcher.LAUNCHER) .then() - .isVisible(LAUNCHER_COMPONENT) + .isVisible(ComponentNameMatcher.LAUNCHER) } } @@ -187,8 +187,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt index 7680f4dfa1d5..4788507c1443 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt @@ -16,9 +16,11 @@ package com.android.wm.shell.flicker.pip +import android.app.Activity +import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -26,14 +28,19 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.entireScreenCovered +import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper import com.android.server.wm.flicker.helpers.WindowUtils -import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.traces.common.FlickerComponentName -import com.android.wm.shell.flicker.helpers.FixedAppHelper +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd +import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule +import com.android.server.wm.flicker.testapp.ActivityOptions.Pip.ACTION_ENTER_PIP +import com.android.server.wm.flicker.testapp.ActivityOptions.PortraitOnlyActivity.EXTRA_FIXED_ORIENTATION +import com.android.server.wm.traces.common.ComponentNameMatcher import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT -import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION -import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP +import org.junit.Assume +import org.junit.Before import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -66,7 +73,7 @@ import org.junit.runners.Parameterized class EnterPipToOtherOrientationTest( testSpec: FlickerTestParameter ) : PipTransition(testSpec) { - private val testApp = FixedAppHelper(instrumentation) + private val testApp = FixedOrientationAppHelper(instrumentation) private val startingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_90) private val endingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_0) @@ -75,42 +82,58 @@ class EnterPipToOtherOrientationTest( */ override val transition: FlickerBuilder.() -> Unit get() = { - setupAndTeardown(this) - setup { - eachRun { - // Launch a portrait only app on the fullscreen stack - testApp.launchViaIntent(wmHelper, stringExtras = mapOf( - EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString())) - // Launch the PiP activity fixed as landscape - pipApp.launchViaIntent(wmHelper, stringExtras = mapOf( - EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())) - } + RemoveAllTasksButHomeRule.removeAllTasksButHome() + device.wakeUpAndGoToHomeScreen() + + // Launch a portrait only app on the fullscreen stack + testApp.launchViaIntent( + wmHelper, stringExtras = mapOf( + EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString() + ) + ) + // Launch the PiP activity fixed as landscape + pipApp.launchViaIntent( + wmHelper, stringExtras = mapOf( + EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString() + ) + ) } teardown { - eachRun { - pipApp.exit(wmHelper) - testApp.exit(wmHelper) - } + setRotation(Surface.ROTATION_0) + RemoveAllTasksButHomeRule.removeAllTasksButHome() + pipApp.exit(wmHelper) + testApp.exit(wmHelper) } transitions { // Enter PiP, and assert that the PiP is within bounds now that the device is back // in portrait broadcastActionTrigger.doAction(ACTION_ENTER_PIP) - wmHelper.waitPipShown() - wmHelper.waitForAppTransitionIdle() // during rotation the status bar becomes invisible and reappears at the end - wmHelper.waitForNavBarStatusBarVisible() + wmHelper.StateSyncBuilder() + .withPipShown() + .withNavOrTaskBarVisible() + .withStatusBarVisible() + .waitForAndVerify() } } /** - * Checks that the [FlickerComponentName.NAV_BAR] has the correct position at + * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation] + * to fix a orientation, Tablets instead keep the same orientation and add letterboxes + */ + @Before + fun setup() { + Assume.assumeFalse(testSpec.isTablet) + } + + /** + * Checks that the [ComponentNameMatcher.NAV_BAR] has the correct position at * the start and end of the transition */ @FlakyTest @Test - override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() + override fun navBarLayerPositionAtStartAndEnd() = testSpec.navBarLayerPositionAtStartAndEnd() /** * Checks that all parts of the screen are covered at the start and end of the transition @@ -119,7 +142,7 @@ class EnterPipToOtherOrientationTest( */ @Presubmit @Test - override fun entireScreenCovered() = testSpec.entireScreenCovered(allStates = false) + fun entireScreenCoveredAtStartAndEnd() = testSpec.entireScreenCovered(allStates = false) /** * Checks [pipApp] window remains visible and on top throughout the transition @@ -128,7 +151,7 @@ class EnterPipToOtherOrientationTest( @Test fun pipAppWindowIsAlwaysOnTop() { testSpec.assertWm { - isAppWindowOnTop(pipApp.component) + isAppWindowOnTop(pipApp) } } @@ -139,7 +162,7 @@ class EnterPipToOtherOrientationTest( @Test fun testAppWindowInvisibleOnStart() { testSpec.assertWmStart { - isAppWindowInvisible(testApp.component) + isAppWindowInvisible(testApp) } } @@ -150,7 +173,7 @@ class EnterPipToOtherOrientationTest( @Test fun testAppWindowVisibleOnEnd() { testSpec.assertWmEnd { - isAppWindowVisible(testApp.component) + isAppWindowVisible(testApp) } } @@ -161,7 +184,7 @@ class EnterPipToOtherOrientationTest( @Test fun testAppLayerInvisibleOnStart() { testSpec.assertLayersStart { - isInvisible(testApp.component) + isInvisible(testApp) } } @@ -172,7 +195,7 @@ class EnterPipToOtherOrientationTest( @Test fun testAppLayerVisibleOnEnd() { testSpec.assertLayersEnd { - isVisible(testApp.component) + isVisible(testApp) } } @@ -184,7 +207,7 @@ class EnterPipToOtherOrientationTest( @Test fun pipAppLayerCoversFullScreenOnStart() { testSpec.assertLayersStart { - visibleRegion(pipApp.component).coversExactly(startingBounds) + visibleRegion(pipApp).coversExactly(startingBounds) } } @@ -196,13 +219,19 @@ class EnterPipToOtherOrientationTest( @Test fun testAppPlusPipLayerCoversFullScreenOnEnd() { testSpec.assertLayersEnd { - val pipRegion = visibleRegion(pipApp.component).region - visibleRegion(testApp.component) + val pipRegion = visibleRegion(pipApp).region + visibleRegion(testApp) .plus(pipRegion) .coversExactly(endingBounds) } } + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + companion object { /** * Creates the test configurations. @@ -214,8 +243,9 @@ class EnterPipToOtherOrientationTest( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests( + supportedRotations = listOf(Surface.ROTATION_0) + ) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt index 990872f58dc1..628599160c65 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt @@ -18,14 +18,14 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import com.android.server.wm.flicker.FlickerTestParameter -import com.android.wm.shell.flicker.helpers.FixedAppHelper +import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper import org.junit.Test /** * Base class for pip expand tests */ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTransition(testSpec) { - protected val testApp = FixedAppHelper(instrumentation) + protected val testApp = FixedOrientationAppHelper(instrumentation) /** * Checks that the pip app window remains inside the display bounds throughout the whole @@ -34,7 +34,7 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans @Presubmit @Test open fun pipAppWindowRemainInsideVisibleBounds() { - testSpec.assertWmVisibleRegion(pipApp.component) { + testSpec.assertWmVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -46,7 +46,7 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans @Presubmit @Test open fun pipAppLayerRemainInsideVisibleBounds() { - testSpec.assertLayersVisibleRegion(pipApp.component) { + testSpec.assertLayersVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -62,11 +62,11 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans // when the activity is STOPPING, sometimes it becomes invisible in an entry before // the window, sometimes in the same entry. This occurs because we log 1x per frame // thus we ignore activity here - isAppWindowVisible(testApp.component) - .isAppWindowOnTop(pipApp.component) - .then() - .isAppWindowInvisible(testApp.component) - .isAppWindowVisible(pipApp.component) + isAppWindowVisible(testApp) + .isAppWindowOnTop(pipApp) + .then() + .isAppWindowInvisible(testApp) + .isAppWindowVisible(pipApp) } } @@ -78,11 +78,11 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans @Test open fun showBothAppLayersThenHidePip() { testSpec.assertLayers { - isVisible(testApp.component) - .isVisible(pipApp.component) - .then() - .isInvisible(testApp.component) - .isVisible(pipApp.component) + isVisible(testApp) + .isVisible(pipApp) + .then() + .isInvisible(testApp) + .isVisible(pipApp) } } @@ -94,10 +94,10 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans @Test open fun testPlusPipAppsCoverFullScreenAtStart() { testSpec.assertLayersStart { - val pipRegion = visibleRegion(pipApp.component).region - visibleRegion(testApp.component) - .plus(pipRegion) - .coversExactly(displayBounds) + val pipRegion = visibleRegion(pipApp).region + visibleRegion(testApp) + .plus(pipRegion) + .coversExactly(displayBounds) } } @@ -109,7 +109,7 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans @Test open fun pipAppCoversFullScreenAtEnd() { testSpec.assertLayersEnd { - visibleRegion(pipApp.component).coversExactly(displayBounds) + visibleRegion(pipApp).coversExactly(displayBounds) } } @@ -119,12 +119,16 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans @Presubmit @Test open fun pipLayerExpands() { - val layerName = pipApp.component.toLayerName() testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } pipLayerList.zipWithNext { previous, current -> current.visibleRegion.coversAtLeast(previous.visibleRegion.region) } } } + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun entireScreenCovered() = super.entireScreenCovered() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt index 0b4bc761838d..39be89d2592b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt @@ -19,10 +19,10 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface import com.android.server.wm.flicker.FlickerTestParameter -import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.traces.common.ComponentNameMatcher.Companion.LAUNCHER import org.junit.Test /** @@ -30,16 +30,12 @@ import org.junit.Test */ abstract class ExitPipTransition(testSpec: FlickerTestParameter) : PipTransition(testSpec) { override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = true) { + get() = buildTransition { setup { - eachRun { - this.setRotation(testSpec.startRotation) - } + this.setRotation(testSpec.startRotation) } teardown { - eachRun { - this.setRotation(Surface.ROTATION_0) - } + this.setRotation(Surface.ROTATION_0) } } @@ -57,28 +53,28 @@ abstract class ExitPipTransition(testSpec: FlickerTestParameter) : PipTransition // and isAppWindowInvisible in the same assertion block. testSpec.assertWm { this.invoke("hasPipWindow") { - it.isPinned(pipApp.component) - .isAppWindowVisible(pipApp.component) - .isAppWindowOnTop(pipApp.component) + it.isPinned(pipApp) + .isAppWindowVisible(pipApp) + .isAppWindowOnTop(pipApp) }.then().invoke("!hasPipWindow") { - it.isNotPinned(pipApp.component) - .isAppWindowNotOnTop(pipApp.component) + it.isNotPinned(pipApp) + .isAppWindowNotOnTop(pipApp) } } - testSpec.assertWmEnd { isAppWindowInvisible(pipApp.component) } + testSpec.assertWmEnd { isAppWindowInvisible(pipApp) } } else { testSpec.assertWm { this.invoke("hasPipWindow") { - it.isPinned(pipApp.component).isAppWindowVisible(pipApp.component) + it.isPinned(pipApp).isAppWindowVisible(pipApp) }.then().invoke("!hasPipWindow") { - it.isNotPinned(pipApp.component).isAppWindowInvisible(pipApp.component) + it.isNotPinned(pipApp).isAppWindowInvisible(pipApp) } } } } /** - * Checks that [pipApp] and [LAUNCHER_COMPONENT] layers are visible at the start + * Checks that [pipApp] and [LAUNCHER] layers are visible at the start * of the transition. Then [pipApp] layer becomes invisible, and remains invisible * until the end of the transition */ @@ -86,11 +82,11 @@ abstract class ExitPipTransition(testSpec: FlickerTestParameter) : PipTransition @Test open fun pipLayerBecomesInvisible() { testSpec.assertLayers { - this.isVisible(pipApp.component) - .isVisible(LAUNCHER_COMPONENT) + this.isVisible(pipApp) + .isVisible(LAUNCHER) .then() - .isInvisible(pipApp.component) - .isVisible(LAUNCHER_COMPONENT) + .isInvisible(pipApp) + .isVisible(LAUNCHER) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt index 0768e82e491c..c2fd0d78f0d5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt @@ -16,8 +16,8 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -54,7 +54,6 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group3 -@FlakyTest(bugId = 219750830) class ExitPipViaExpandButtonClickTest( testSpec: FlickerTestParameter ) : ExitPipToAppTransition(testSpec) { @@ -63,22 +62,27 @@ class ExitPipViaExpandButtonClickTest( * Defines the transition used to run the test */ override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = true) { + get() = buildTransition { setup { - eachRun { - // launch an app behind the pip one - testApp.launchViaIntent(wmHelper) - } + // launch an app behind the pip one + testApp.launchViaIntent(wmHelper) } transitions { // This will bring PipApp to fullscreen pipApp.expandPipWindowToApp(wmHelper) // Wait until the other app is no longer visible - wmHelper.waitForWindowSurfaceDisappeared(testApp.component) + wmHelper.StateSyncBuilder() + .withWindowSurfaceDisappeared(testApp) + .waitForAndVerify() } } /** {@inheritDoc} */ + @FlakyTest(bugId = 227313015) + @Test + override fun entireScreenCovered() = super.entireScreenCovered() + + /** {@inheritDoc} */ @FlakyTest(bugId = 197726610) @Test override fun pipLayerExpands() = super.pipLayerExpands() @@ -94,7 +98,7 @@ class ExitPipViaExpandButtonClickTest( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3) + supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt index c6a705dacb8d..0d75e02bd467 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt @@ -16,9 +16,9 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -62,34 +62,39 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit * Defines the transition used to run the test */ override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = true) { + get() = buildTransition { setup { - eachRun { - // launch an app behind the pip one - testApp.launchViaIntent(wmHelper) - } + // launch an app behind the pip one + testApp.launchViaIntent(wmHelper) } transitions { // This will bring PipApp to fullscreen pipApp.exitPipToFullScreenViaIntent(wmHelper) // Wait until the other app is no longer visible - wmHelper.waitForWindowSurfaceDisappeared(testApp.component) + wmHelper.StateSyncBuilder() + .withWindowSurfaceDisappeared(testApp) + .waitForAndVerify() } } /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) + @FlakyTest @Test - override fun statusBarLayerRotatesScales() { + override fun entireScreenCovered() = super.entireScreenCovered() + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() { Assume.assumeFalse(isShellTransitionsEnabled) - super.statusBarLayerRotatesScales() + super.statusBarLayerPositionAtStartAndEnd() } @Presubmit @Test fun statusBarLayerRotatesScales_ShellTransit() { Assume.assumeTrue(isShellTransitionsEnabled) - super.statusBarLayerRotatesScales() + super.statusBarLayerPositionAtStartAndEnd() } /** {@inheritDoc} */ @@ -118,7 +123,7 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3) + supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt index 437ad893f1d9..3bffef0ca793 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt @@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -64,18 +63,13 @@ class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTran } } - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - /** * Checks that the focus changes between the pip menu window and the launcher when clicking the * dismiss button on pip menu to close the pip window. */ @Presubmit @Test - fun focusDoesNotChange() { + fun focusChanges() { testSpec.assertEventLog { this.focusChanges("PipMenuView", "NexusLauncherActivity") } @@ -92,8 +86,7 @@ class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTran @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt index 128703ad332c..75d25e6ef67e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt @@ -18,13 +18,13 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.traces.common.ComponentNameMatcher import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -58,25 +58,31 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti get() = { super.transition(this) transitions { - val pipRegion = wmHelper.getWindowRegion(pipApp.component).bounds + val pipRegion = wmHelper.getWindowRegion(pipApp).bounds val pipCenterX = pipRegion.centerX() val pipCenterY = pipRegion.centerY() val displayCenterX = device.displayWidth / 2 - device.swipe(pipCenterX, pipCenterY, displayCenterX, device.displayHeight, 10) - wmHelper.waitPipGone() - wmHelper.waitForWindowSurfaceDisappeared(pipApp.component) - wmHelper.waitForAppTransitionIdle() + val barComponent = if (testSpec.isTablet) { + ComponentNameMatcher.TASK_BAR + } else { + ComponentNameMatcher.NAV_BAR + } + val barLayerHeight = wmHelper.currentState.layerState + .getLayerWithBuffer(barComponent) + ?.visibleRegion + ?.height ?: error("Couldn't find Nav or Task bar layer") + // The dismiss button doesn't appear at the complete bottom of the screen, + val displayY = device.displayHeight - barLayerHeight + device.swipe(pipCenterX, pipCenterY, displayCenterX, displayY, 50) + // Wait until the other app is no longer visible + wmHelper.StateSyncBuilder() + .withPipGone() + .withWindowSurfaceDisappeared(pipApp) + .withAppTransitionIdle() + .waitForAndVerify() } } - @FlakyTest - @Test - override fun pipWindowBecomesInvisible() = super.pipWindowBecomesInvisible() - - @FlakyTest - @Test - override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible() - /** * Checks that the focus doesn't change between windows during the transition */ @@ -99,8 +105,7 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.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 28b7fc9bd29e..513ce95042d0 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 @@ -16,16 +16,16 @@ package com.android.wm.shell.flicker.pip -import androidx.test.filters.FlakyTest +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import android.view.Surface import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory -import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.traces.common.ComponentNameMatcher import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -56,7 +56,7 @@ import org.junit.runners.Parameterized @Group3 class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = true) { + get() = buildTransition { transitions { pipApp.doubleClickPipWindow(wmHelper) } @@ -69,7 +69,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @Presubmit @Test fun pipWindowRemainInsideVisibleBounds() { - testSpec.assertWmVisibleRegion(pipApp.component) { + testSpec.assertWmVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -81,7 +81,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @Presubmit @Test fun pipLayerRemainInsideVisibleBounds() { - testSpec.assertLayersVisibleRegion(pipApp.component) { + testSpec.assertLayersVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -93,7 +93,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @Test fun pipWindowIsAlwaysVisible() { testSpec.assertWm { - isAppWindowVisible(pipApp.component) + isAppWindowVisible(pipApp) } } @@ -104,19 +104,18 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @Test fun pipLayerIsAlwaysVisible() { testSpec.assertLayers { - isVisible(pipApp.component) + isVisible(pipApp) } } /** * Checks that the visible region of [pipApp] always expands during the animation */ - @FlakyTest(bugId = 228012337) + @Presubmit @Test fun pipLayerExpands() { - val layerName = pipApp.component.toLayerName() testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } pipLayerList.zipWithNext { previous, current -> current.visibleRegion.coversAtLeast(previous.visibleRegion.region) } @@ -126,9 +125,8 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @Presubmit @Test fun pipSameAspectRatio() { - val layerName = pipApp.component.toLayerName() testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible } pipLayerList.zipWithNext { previous, current -> current.visibleRegion.isSameAspectRatio(previous.visibleRegion) } @@ -142,18 +140,18 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @Test fun windowIsAlwaysPinned() { testSpec.assertWm { - this.invoke("hasPipWindow") { it.isPinned(pipApp.component) } + this.invoke("hasPipWindow") { it.isPinned(pipApp) } } } /** - * Checks [pipApp] layer remains visible throughout the animation + * Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation */ @Presubmit @Test fun launcherIsAlwaysVisible() { testSpec.assertLayers { - isVisible(LAUNCHER_COMPONENT) + isVisible(ComponentNameMatcher.LAUNCHER) } } @@ -168,10 +166,6 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition } } - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - companion object { /** * Creates the test configurations. @@ -183,8 +177,9 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests( + supportedRotations = listOf(Surface.ROTATION_0) + ) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt index 8729bb6776f0..746ce913c587 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt @@ -16,15 +16,15 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.Presubmit +import android.platform.test.annotations.RequiresDevice import android.view.Surface -import androidx.test.filters.FlakyTest -import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.traces.region.RegionSubject +import com.android.wm.shell.flicker.Direction import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -32,14 +32,14 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** - * Test Pip movement with Launcher shelf height change (decrease). + * Test Pip movement with Launcher shelf height change (increase). * - * To run this test: `atest WMShellFlickerTests:MovePipDownShelfHeightChangeTest` + * To run this test: `atest WMShellFlickerTests:MovePipUpShelfHeightChangeTest` * * Actions: * Launch [pipApp] in pip mode - * Launch [testApp] * Press home + * Launch [testApp] * Check if pip window moves down (visually) * * Notes: @@ -55,35 +55,41 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group3 -open class MovePipDownShelfHeightChangeTest( +class MovePipDownShelfHeightChangeTest( testSpec: FlickerTestParameter ) : MovePipShelfHeightTransition(testSpec) { +// @Before +// fun before() { +// Assume.assumeFalse(isShellTransitionsEnabled) +// } + /** * Defines the transition used to run the test */ override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = false) { + get() = buildTransition { teardown { - eachRun { - testApp.launchViaIntent(wmHelper) - } - test { - testApp.exit(wmHelper) - } + tapl.pressHome() + testApp.exit(wmHelper) } transitions { - taplInstrumentation.pressHome() + testApp.launchViaIntent(wmHelper) } } - override fun assertRegionMovement(previous: RegionSubject, current: RegionSubject) { - current.isHigherOrEqual(previous.region) - } + /** + * Checks that the visible region of [pipApp] window always moves down during the animation. + */ + @Presubmit + @Test + fun pipWindowMovesDown() = pipWindowMoves(Direction.DOWN) - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) + /** + * Checks that the visible region of [pipApp] layer always moves down during the animation. + */ + @Presubmit @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() + fun pipLayerMovesDown() = pipLayerMoves(Direction.DOWN) companion object { /** @@ -96,7 +102,8 @@ open class MovePipDownShelfHeightChangeTest( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3) + supportedRotations = listOf(Surface.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 0499e7de9a0a..5f9419694c13 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 @@ -17,10 +17,10 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit -import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper import com.android.server.wm.flicker.traces.region.RegionSubject -import com.android.wm.shell.flicker.helpers.FixedAppHelper +import com.android.wm.shell.flicker.Direction import org.junit.Test /** @@ -29,13 +29,7 @@ import org.junit.Test abstract class MovePipShelfHeightTransition( testSpec: FlickerTestParameter ) : PipTransition(testSpec) { - protected val taplInstrumentation = LauncherInstrumentation() - protected val testApp = FixedAppHelper(instrumentation) - - /** - * Checks if the window movement direction is valid - */ - protected abstract fun assertRegionMovement(previous: RegionSubject, current: RegionSubject) + protected val testApp = FixedOrientationAppHelper(instrumentation) /** * Checks [pipApp] window remains visible throughout the animation @@ -44,7 +38,7 @@ abstract class MovePipShelfHeightTransition( @Test open fun pipWindowIsAlwaysVisible() { testSpec.assertWm { - isAppWindowVisible(pipApp.component) + isAppWindowVisible(pipApp) } } @@ -55,7 +49,7 @@ abstract class MovePipShelfHeightTransition( @Test open fun pipLayerIsAlwaysVisible() { testSpec.assertLayers { - isVisible(pipApp.component) + isVisible(pipApp) } } @@ -66,7 +60,7 @@ abstract class MovePipShelfHeightTransition( @Presubmit @Test open fun pipWindowRemainInsideVisibleBounds() { - testSpec.assertWmVisibleRegion(pipApp.component) { + testSpec.assertWmVisibleRegion(pipApp) { coversAtMost(displayBounds) } } @@ -78,39 +72,52 @@ abstract class MovePipShelfHeightTransition( @Presubmit @Test open fun pipLayerRemainInsideVisibleBounds() { - testSpec.assertLayersVisibleRegion(pipApp.component) { + testSpec.assertLayersVisibleRegion(pipApp) { coversAtMost(displayBounds) } } /** - * Checks that the visible region of [pipApp] always moves in the correct direction + * Checks that the visible region of [pipApp] window always moves in the specified direction * during the animation. */ - @Presubmit - @Test - open fun pipWindowMoves() { - val windowName = pipApp.component.toWindowName() + protected fun pipWindowMoves(direction: Direction) { testSpec.assertWm { - val pipWindowList = this.windowStates { it.name.contains(windowName) && it.isVisible } - pipWindowList.zipWithNext { previous, current -> - assertRegionMovement(previous.frame, current.frame) + val pipWindowFrameList = this.windowStates { + pipApp.windowMatchesAnyOf(it) && it.isVisible + }.map { it.frame } + when (direction) { + Direction.UP -> assertRegionMovementUp(pipWindowFrameList) + Direction.DOWN -> assertRegionMovementDown(pipWindowFrameList) + else -> error("Unhandled direction") } } } /** - * Checks that the visible region of [pipApp] always moves up during the animation + * Checks that the visible region of [pipApp] layer always moves in the specified direction + * during the animation. */ - @Presubmit - @Test - open fun pipLayerMoves() { - val layerName = pipApp.component.toLayerName() + protected fun pipLayerMoves(direction: Direction) { testSpec.assertLayers { - val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } - pipLayerList.zipWithNext { previous, current -> - assertRegionMovement(previous.visibleRegion, current.visibleRegion) + val pipLayerRegionList = this.layers { + pipApp.layerMatchesAnyOf(it) && it.isVisible + }.map { it.visibleRegion } + when (direction) { + Direction.UP -> assertRegionMovementUp(pipLayerRegionList) + Direction.DOWN -> assertRegionMovementDown(pipLayerRegionList) + else -> error("Unhandled direction") } } } -}
\ No newline at end of file + + private fun assertRegionMovementDown(regions: List<RegionSubject>) { + regions.zipWithNext { previous, current -> current.isLowerOrEqual(previous) } + regions.last().isLower(regions.first()) + } + + private fun assertRegionMovementUp(regions: List<RegionSubject>) { + regions.zipWithNext { previous, current -> current.isHigherOrEqual(previous.region) } + regions.last().isHigher(regions.first()) + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt index 388b5e0b5e47..93e7d5ca45ad 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt @@ -16,18 +16,15 @@ package com.android.wm.shell.flicker.pip -import androidx.test.filters.FlakyTest -import android.platform.test.annotations.RequiresDevice +import android.platform.test.annotations.Presubmit import android.view.Surface +import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled -import com.android.server.wm.flicker.traces.region.RegionSubject -import org.junit.Assume -import org.junit.Before +import com.android.wm.shell.flicker.Direction import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -35,14 +32,14 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** - * Test Pip movement with Launcher shelf height change (increase). + * Test Pip movement with Launcher shelf height change (decrease). * - * To run this test: `atest WMShellFlickerTests:MovePipUpShelfHeightChangeTest` + * To run this test: `atest WMShellFlickerTests:MovePipDownShelfHeightChangeTest` * * Actions: * Launch [pipApp] in pip mode - * Press home * Launch [testApp] + * Press home * Check if pip window moves up (visually) * * Notes: @@ -58,40 +55,38 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group3 -class MovePipUpShelfHeightChangeTest( +open class MovePipUpShelfHeightChangeTest( testSpec: FlickerTestParameter ) : MovePipShelfHeightTransition(testSpec) { - @Before - fun before() { - Assume.assumeFalse(isShellTransitionsEnabled) - } - /** * Defines the transition used to run the test */ override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = false) { - teardown { - eachRun { - taplInstrumentation.pressHome() - } - test { - testApp.exit(wmHelper) - } + get() = buildTransition() { + setup { + testApp.launchViaIntent(wmHelper) } transitions { - testApp.launchViaIntent(wmHelper) + tapl.pressHome() + } + teardown { + testApp.exit(wmHelper) } } - override fun assertRegionMovement(previous: RegionSubject, current: RegionSubject) { - current.isLowerOrEqual(previous.region) - } + /** + * Checks that the visible region of [pipApp] window always moves up during the animation. + */ + @Presubmit + @Test + fun pipWindowMovesUp() = pipWindowMoves(Direction.UP) - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) + /** + * Checks that the visible region of [pipApp] layer always moves up during the animation. + */ + @Presubmit @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() + fun pipLayerMovesUp() = pipLayerMoves(Direction.UP) companion object { /** @@ -104,7 +99,8 @@ class MovePipUpShelfHeightChangeTest( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3) + supportedRotations = listOf(Surface.ROTATION_0) + ) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt index 1e30f6b83874..2aa0da95dfd5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt @@ -18,18 +18,17 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.ImeAppHelper import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.traces.common.FlickerComponentName -import com.android.wm.shell.flicker.helpers.ImeAppHelper +import com.android.server.wm.traces.common.ComponentNameMatcher import org.junit.Assume.assumeFalse import org.junit.Before import org.junit.FixMethodOrder @@ -47,7 +46,6 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group4 -@FlakyTest(bugId = 218604389) open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { private val imeApp = ImeAppHelper(instrumentation) @@ -56,19 +54,16 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS assumeFalse(isShellTransitionsEnabled) } + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = false) { + get() = buildTransition { setup { - test { - imeApp.launchViaIntent(wmHelper) - setRotation(testSpec.startRotation) - } + imeApp.launchViaIntent(wmHelper) + setRotation(testSpec.startRotation) } teardown { - test { - imeApp.exit(wmHelper) - setRotation(Surface.ROTATION_0) - } + imeApp.exit(wmHelper) + setRotation(Surface.ROTATION_0) } transitions { // open the soft keyboard @@ -80,18 +75,13 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS } } - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - /** * Ensure the pip window remains visible throughout any keyboard interactions */ @Presubmit @Test open fun pipInVisibleBounds() { - testSpec.assertWmVisibleRegion(pipApp.component) { + testSpec.assertWmVisibleRegion(pipApp) { val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation) coversAtMost(displayBounds) } @@ -104,7 +94,7 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS @Test open fun pipIsAboveAppWindow() { testSpec.assertWmTag(TAG_IME_VISIBLE) { - isAboveWindow(FlickerComponentName.IME, pipApp.component) + isAboveWindow(ComponentNameMatcher.IME, pipApp) } } @@ -115,8 +105,7 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt index fe51228230cb..3e00b19e2f19 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt @@ -44,5 +44,6 @@ class PipKeyboardTestShellTransit(testSpec: FlickerTestParameter) : PipKeyboardT @Presubmit @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() -}
\ No newline at end of file + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt index 9fad4997e63a..0fce64ea073b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt @@ -16,20 +16,21 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group4 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.entireScreenCovered +import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.helpers.WindowUtils +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.wm.shell.flicker.helpers.FixedAppHelper +import org.junit.Assume +import org.junit.Before import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -61,19 +62,20 @@ import org.junit.runners.Parameterized @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group4 open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { - private val fixedApp = FixedAppHelper(instrumentation) + private val testApp = SimpleAppHelper(instrumentation) private val screenBoundsStart = WindowUtils.getDisplayBounds(testSpec.startRotation) private val screenBoundsEnd = WindowUtils.getDisplayBounds(testSpec.endRotation) + @Before + open fun before() { + Assume.assumeFalse(isShellTransitionsEnabled) + } + override val transition: FlickerBuilder.() -> Unit - get() = buildTransition(eachRun = false) { + get() = buildTransition { setup { - test { - fixedApp.launchViaIntent(wmHelper) - } - eachRun { - setRotation(testSpec.startRotation) - } + testApp.launchViaIntent(wmHelper) + setRotation(testSpec.startRotation) } transitions { setRotation(testSpec.endRotation) @@ -81,38 +83,55 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS } /** - * Checks that all parts of the screen are covered at the start and end of the transition + * Checks the position of the navigation bar at the start and end of the transition + */ + @FlakyTest(bugId = 240499181) + @Test + override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd() + + /** + * Checks that [testApp] layer is within [screenBoundsStart] at the start of the transition */ @Presubmit @Test - override fun entireScreenCovered() = testSpec.entireScreenCovered() + fun fixedAppLayer_StartingBounds() { + testSpec.assertLayersStart { + visibleRegion(testApp).coversAtMost(screenBoundsStart) + } + } /** - * Checks the position of the navigation bar at the start and end of the transition + * Checks that [testApp] layer is within [screenBoundsEnd] at the end of the transition */ - @FlakyTest + @Presubmit @Test - override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() + fun fixedAppLayer_EndingBounds() { + testSpec.assertLayersEnd { + visibleRegion(testApp).coversAtMost(screenBoundsEnd) + } + } /** - * Checks that [fixedApp] layer is within [screenBoundsStart] at the start of the transition + * Checks that [testApp] plus [pipApp] layers are within [screenBoundsEnd] at the start + * of the transition */ @Presubmit @Test - fun appLayerRotates_StartingBounds() { + fun appLayers_StartingBounds() { testSpec.assertLayersStart { - visibleRegion(fixedApp.component).coversExactly(screenBoundsStart) + visibleRegion(testApp.or(pipApp)).coversExactly(screenBoundsStart) } } /** - * Checks that [fixedApp] layer is within [screenBoundsEnd] at the end of the transition + * Checks that [testApp] plus [pipApp] layers are within [screenBoundsEnd] at the end + * of the transition */ @Presubmit @Test - fun appLayerRotates_EndingBounds() { + fun appLayers_EndingBounds() { testSpec.assertLayersEnd { - visibleRegion(fixedApp.component).coversExactly(screenBoundsEnd) + visibleRegion(testApp.or(pipApp)).coversExactly(screenBoundsEnd) } } @@ -121,7 +140,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS */ private fun pipLayerRotates_StartingBounds_internal() { testSpec.assertLayersStart { - visibleRegion(pipApp.component).coversAtMost(screenBoundsStart) + visibleRegion(pipApp).coversAtMost(screenBoundsStart) } } @@ -141,34 +160,40 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS @Test fun pipLayerRotates_EndingBounds() { testSpec.assertLayersEnd { - visibleRegion(pipApp.component).coversAtMost(screenBoundsEnd) + visibleRegion(pipApp).coversAtMost(screenBoundsEnd) } } /** - * Ensure that the [pipApp] window does not obscure the [fixedApp] at the start of the + * Ensure that the [pipApp] window does not obscure the [testApp] at the start of the * transition */ @Presubmit @Test fun pipIsAboveFixedAppWindow_Start() { testSpec.assertWmStart { - isAboveWindow(pipApp.component, fixedApp.component) + isAboveWindow(pipApp, testApp) } } /** - * Ensure that the [pipApp] window does not obscure the [fixedApp] at the end of the + * Ensure that the [pipApp] window does not obscure the [testApp] at the end of the * transition */ @Presubmit @Test fun pipIsAboveFixedAppWindow_End() { testSpec.assertWmEnd { - isAboveWindow(pipApp.component, fixedApp.component) + isAboveWindow(pipApp, testApp) } } + @FlakyTest(bugId = 240499181) + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() { + super.navBarLayerIsVisibleAtStartAndEnd() + } + companion object { /** * Creates the test configurations. @@ -180,8 +205,8 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigRotationTests( - supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90), - repetitions = 3) + supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90) + ) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest_ShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest_ShellTransit.kt new file mode 100644 index 000000000000..737f16ad6024 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest_ShellTransit.kt @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.flicker.pip + +import android.platform.test.annotations.FlakyTest +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.annotation.Group4 +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled +import org.junit.Assume +import org.junit.Before +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test Pip Stack in bounds after rotations. + * + * To run this test: `atest WMShellFlickerTests:PipRotationTest_ShellTransit` + * + * Actions: + * Launch a [pipApp] in pip mode + * Launch another app [fixedApp] (appears below pip) + * Rotate the screen from [testSpec.startRotation] to [testSpec.endRotation] + * (usually, 0->90 and 90->0) + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited from [PipTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group4 +@FlakyTest(bugId = 239575053) +class PipRotationTest_ShellTransit(testSpec: FlickerTestParameter) : PipRotationTest(testSpec) { + @Before + override fun before() { + Assume.assumeTrue(isShellTransitionsEnabled) + } + + /** {@inheritDoc} */ + @FlakyTest + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt deleted file mode 100644 index 7ba085d3cf1a..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import com.android.wm.shell.flicker.FlickerTestBase -import com.android.wm.shell.flicker.helpers.PipAppHelper -import org.junit.Before - -abstract class PipTestBase( - rotationName: String, - rotation: Int -) : FlickerTestBase(rotationName, rotation) { - protected val testApp = PipAppHelper(instrumentation) - - @Before - override fun televisionSetUp() { - /** - * The super implementation assumes ([org.junit.Assume]) that not running on TV, thus - * disabling the test on TV. This test, however, *should run on TV*, so we overriding this - * method and simply leaving it blank. - */ - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt index 8d542c8ec9e6..ff505a04290b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt @@ -18,33 +18,21 @@ package com.android.wm.shell.flicker.pip import android.app.Instrumentation import android.content.Intent -import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.platform.app.InstrumentationRegistry -import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.entireScreenCovered +import com.android.server.wm.flicker.helpers.PipAppHelper import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.server.wm.flicker.navBarLayerIsVisible -import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsVisible import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome -import com.android.server.wm.flicker.statusBarLayerIsVisible -import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsVisible -import com.android.wm.shell.flicker.helpers.PipAppHelper -import com.android.wm.shell.flicker.testapp.Components -import org.junit.Test +import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.wm.shell.flicker.BaseTest -abstract class PipTransition(protected val testSpec: FlickerTestParameter) { - protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() +abstract class PipTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) { protected val pipApp = PipAppHelper(instrumentation) protected val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation) protected val broadcastActionTrigger = BroadcastActionTrigger(instrumentation) - protected abstract val transition: FlickerBuilder.() -> Unit + // Helper class to process test actions by broadcast. protected class BroadcastActionTrigger(private val instrumentation: Instrumentation) { private fun createIntentWithAction(broadcastAction: String): Intent { @@ -67,108 +55,32 @@ abstract class PipTransition(protected val testSpec: FlickerTestParameter) { } } - @FlickerBuilderProvider - fun buildFlicker(): FlickerBuilder { - return FlickerBuilder(instrumentation).apply { - transition(this) - } - } - - /** - * Gets a configuration that handles basic setup and teardown of pip tests - */ - protected val setupAndTeardown: FlickerBuilder.() -> Unit - get() = { - setup { - test { - removeAllTasksButHome() - device.wakeUpAndGoToHomeScreen() - } - } - teardown { - eachRun { - setRotation(Surface.ROTATION_0) - } - test { - removeAllTasksButHome() - pipApp.exit(wmHelper) - } - } - } - /** * Gets a configuration that handles basic setup and teardown of pip tests and that * launches the Pip app for test * * @param eachRun If the pip app should be launched in each run (otherwise only 1x per test) * @param stringExtras Arguments to pass to the PIP launch intent - * @param extraSpec Addicional segment of flicker specification + * @param extraSpec Additional segment of flicker specification */ @JvmOverloads protected open fun buildTransition( - eachRun: Boolean, - stringExtras: Map<String, String> = mapOf(Components.PipActivity.EXTRA_ENTER_PIP to "true"), + stringExtras: Map<String, String> = mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true"), extraSpec: FlickerBuilder.() -> Unit = {} ): FlickerBuilder.() -> Unit { return { - setupAndTeardown(this) - setup { - test { - if (!eachRun) { - pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras) - wmHelper.waitPipShown() - } - } - eachRun { - if (eachRun) { - pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras) - wmHelper.waitPipShown() - } - } + setRotation(Surface.ROTATION_0) + removeAllTasksButHome() + pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras) } teardown { - eachRun { - if (eachRun) { - pipApp.exit(wmHelper) - } - } - test { - if (!eachRun) { - pipApp.exit(wmHelper) - } - } + setRotation(Surface.ROTATION_0) + removeAllTasksButHome() + pipApp.exit(wmHelper) } extraSpec(this) } } - - @Presubmit - @Test - open fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() - - @Presubmit - @Test - open fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() - - @Presubmit - @Test - open fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() - - @Presubmit - @Test - open fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible() - - @Presubmit - @Test - open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() - - @Presubmit - @Test - open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - - @Presubmit - @Test - open fun entireScreenCovered() = testSpec.entireScreenCovered() -}
\ No newline at end of file +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt index 51339a1deb4b..30332f6c4aaf 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt @@ -16,9 +16,11 @@ package com.android.wm.shell.flicker.pip +import android.app.Activity +import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -29,9 +31,11 @@ import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome +import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.server.wm.flicker.testapp.ActivityOptions.PortraitOnlyActivity.EXTRA_FIXED_ORIENTATION import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE -import com.android.wm.shell.flicker.testapp.Components -import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION +import org.junit.Assume +import org.junit.Before import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -53,46 +57,53 @@ open class SetRequestedOrientationWhilePinnedTest( private val startingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_0) private val endingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_90) + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = { setup { - test { - removeAllTasksButHome() - device.wakeUpAndGoToHomeScreen() - } - eachRun { - // Launch the PiP activity fixed as landscape. - pipApp.launchViaIntent(wmHelper, stringExtras = mapOf( - EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())) - // Enter PiP. - broadcastActionTrigger.doAction(Components.PipActivity.ACTION_ENTER_PIP) - wmHelper.waitPipShown() - wmHelper.waitForRotation(Surface.ROTATION_0) - wmHelper.waitForAppTransitionIdle() - // System bar may fade out during fixed rotation. - wmHelper.waitForNavBarStatusBarVisible() - } + removeAllTasksButHome() + device.wakeUpAndGoToHomeScreen() + + // Launch the PiP activity fixed as landscape. + pipApp.launchViaIntent(wmHelper, stringExtras = mapOf( + EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())) + // Enter PiP. + broadcastActionTrigger.doAction(ActivityOptions.Pip.ACTION_ENTER_PIP) + // System bar may fade out during fixed rotation. + wmHelper.StateSyncBuilder() + .withPipShown() + .withRotation(Surface.ROTATION_0) + .withNavOrTaskBarVisible() + .withStatusBarVisible() + .waitForAndVerify() } teardown { - eachRun { - pipApp.exit(wmHelper) - setRotation(Surface.ROTATION_0) - } - test { - removeAllTasksButHome() - } + pipApp.exit(wmHelper) + setRotation(Surface.ROTATION_0) + removeAllTasksButHome() } transitions { // Launch the activity back into fullscreen and ensure that it is now in landscape pipApp.launchViaIntent(wmHelper) - wmHelper.waitForFullScreenApp(pipApp.component) - wmHelper.waitForRotation(Surface.ROTATION_90) - wmHelper.waitForAppTransitionIdle() // System bar may fade out during fixed rotation. - wmHelper.waitForNavBarStatusBarVisible() + wmHelper.StateSyncBuilder() + .withFullScreenApp(pipApp) + .withRotation(Surface.ROTATION_90) + .withNavOrTaskBarVisible() + .withStatusBarVisible() + .waitForAndVerify() } } + /** + * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation] + * to fix a orientation, Tablets instead keep the same orientation and add letterboxes + */ + @Before + fun setup() { + Assume.assumeFalse(testSpec.isTablet) + } + @Presubmit @Test fun displayEndsAt90Degrees() { @@ -101,23 +112,27 @@ open class SetRequestedOrientationWhilePinnedTest( } } + /** {@inheritDoc} */ @Presubmit @Test - override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() + override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd() + /** {@inheritDoc} */ @Presubmit @Test - override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible() + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + /** {@inheritDoc} */ @FlakyTest @Test - override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() + override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd() @Presubmit @Test fun pipWindowInsideDisplay() { testSpec.assertWmStart { - frameRegion(pipApp.component).coversAtMost(startingBounds) + visibleRegion(pipApp).coversAtMost(startingBounds) } } @@ -125,7 +140,7 @@ open class SetRequestedOrientationWhilePinnedTest( @Test fun pipAppShowsOnTop() { testSpec.assertWmEnd { - isAppWindowOnTop(pipApp.component) + isAppWindowOnTop(pipApp) } } @@ -133,7 +148,7 @@ open class SetRequestedOrientationWhilePinnedTest( @Test fun pipLayerInsideDisplay() { testSpec.assertLayersStart { - visibleRegion(pipApp.component).coversAtMost(startingBounds) + visibleRegion(pipApp).coversAtMost(startingBounds) } } @@ -141,7 +156,7 @@ open class SetRequestedOrientationWhilePinnedTest( @Test fun pipAlwaysVisible() { testSpec.assertWm { - this.isAppWindowVisible(pipApp.component) + this.isAppWindowVisible(pipApp) } } @@ -149,17 +164,31 @@ open class SetRequestedOrientationWhilePinnedTest( @Test fun pipAppLayerCoversFullScreen() { testSpec.assertLayersEnd { - visibleRegion(pipApp.component).coversExactly(endingBounds) + visibleRegion(pipApp).coversExactly(endingBounds) } } + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = super.entireScreenCovered() + companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 1) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt new file mode 100644 index 000000000000..cdd768abd5bd --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.flicker.pip.tv + +import android.app.Instrumentation +import androidx.test.uiautomator.By +import androidx.test.uiautomator.BySelector +import androidx.test.uiautomator.UiObject2 +import androidx.test.uiautomator.Until +import com.android.server.wm.flicker.helpers.PipAppHelper +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper + +/** + * Helper class for PIP app on AndroidTV + */ +open class PipAppHelperTv(instrumentation: Instrumentation) : PipAppHelper(instrumentation) { + private val appSelector = By.pkg(`package`).depth(0) + + val ui: UiObject2? + get() = uiDevice.findObject(appSelector) + + private fun focusOnObject(selector: BySelector): Boolean { + // We expect all the focusable UI elements to be arranged in a way so that it is possible + // to "cycle" over all them by clicking the D-Pad DOWN button, going back up to "the top" + // from "the bottom". + repeat(FOCUS_ATTEMPTS) { + uiDevice.findObject(selector)?.apply { if (isFocusedOrHasFocusedChild) return true } + ?: error("The object we try to focus on is gone.") + + uiDevice.pressDPadDown() + uiDevice.waitForIdle() + } + return false + } + + override fun clickObject(resId: String) { + val selector = By.res(`package`, resId) + focusOnObject(selector) || error("Could not focus on `$resId` object") + uiDevice.pressDPadCenter() + } + + @Deprecated( + "Use PipAppHelper.closePipWindow(wmHelper) instead", + ReplaceWith("closePipWindow(wmHelper)") + ) + override fun closePipWindow() { + uiDevice.closeTvPipWindow() + } + + /** + * Taps the pip window and dismisses it by clicking on the X button. + */ + override fun closePipWindow(wmHelper: WindowManagerStateHelper) { + uiDevice.closeTvPipWindow() + + // Wait for animation to complete. + wmHelper.StateSyncBuilder() + .withPipGone() + .withHomeActivityVisible() + .waitForAndVerify() + } + + fun waitUntilClosed(): Boolean { + val appSelector = By.pkg(`package`).depth(0) + return uiDevice.wait(Until.gone(appSelector), APP_CLOSE_WAIT_TIME_MS) + } + + companion object { + private const val FOCUS_ATTEMPTS = 20 + private const val APP_CLOSE_WAIT_TIME_MS = 3_000L + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt index 9c50630095be..a16f5f6f1620 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -14,29 +14,17 @@ * limitations under the License. */ -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.pip.tv import android.app.Instrumentation import android.content.pm.PackageManager -import android.content.pm.PackageManager.FEATURE_LEANBACK -import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY import android.view.Surface import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice -import org.junit.Assume.assumeFalse import org.junit.Before import org.junit.runners.Parameterized -/** - * Base class of all Flicker test that performs common functions for all flicker tests: - * - * - Caches transitions so that a transition is run once and the transition results are used by - * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods - * multiple times. - * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed. - * - Fails tests if results are not available for any test due to jank. - */ -abstract class FlickerTestBase( +abstract class PipTestBase( protected val rotationName: String, protected val rotation: Int ) { @@ -45,16 +33,20 @@ abstract class FlickerTestBase( val packageManager: PackageManager = instrumentation.context.packageManager protected val isTelevision: Boolean by lazy { packageManager.run { - hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY) + hasSystemFeature(PackageManager.FEATURE_LEANBACK) || + hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY) } } + protected val testApp = PipAppHelperTv(instrumentation) - /** - * By default WmShellFlickerTests do not run on TV devices. - * If the test should run on TV - it should override this method. - */ @Before - open fun televisionSetUp() = assumeFalse(isTelevision) + open fun televisionSetUp() { + /** + * The super implementation assumes ([org.junit.Assume]) that not running on TV, thus + * disabling the test on TV. This test, however, *should run on TV*, so we overriding this + * method and simply leaving it blank. + */ + } companion object { @Parameterized.Parameters(name = "{0}") diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt index 49094e609fbc..31fb16ffbd3e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt @@ -43,7 +43,7 @@ class TvPipBasicTest( // Set up ratio and enter Pip testApp.clickObject(radioButtonId) - testApp.clickEnterPipButton() + testApp.clickEnterPipButton(wmHelper) val actualRatio: Float = testApp.ui?.visibleBounds?.ratio ?: fail("Application UI not found") @@ -84,4 +84,4 @@ class TvPipBasicTest( ) } } -}
\ No newline at end of file +} 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 061218a015e4..68dbbfb89b6c 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 @@ -19,8 +19,8 @@ package com.android.wm.shell.flicker.pip.tv 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.testapp.Components import com.android.wm.shell.flicker.wait import org.junit.Assert.assertNull import org.junit.Assert.assertTrue @@ -165,44 +165,44 @@ class TvPipMenuTests : TvPipTestBase() { enterPip_openMenu_assertShown() // PiP menu should contain "No-Op", "Off" and "Clear" buttons... - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_NO_OP) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_NO_OP) ?: fail("\"No-Op\" button should be shown in Pip menu") - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_OFF) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_OFF) ?: fail("\"Off\" button should be shown in Pip menu") - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_CLEAR) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_CLEAR) ?: fail("\"Clear\" button should be shown in Pip menu") // ... and should also contain the "Full screen" and "Close" buttons. assertFullscreenAndCloseButtonsAreShown() - uiDevice.clickTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_OFF) + uiDevice.clickTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_OFF) // Invoking the "Off" action should replace it with the "On" action/button and should // remove the "No-Op" action/button. "Clear" action/button should remain in the menu ... - uiDevice.waitForTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_ON) + uiDevice.waitForTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_ON) ?: fail("\"On\" button should be shown in Pip for a corresponding custom action") assertNull("\"No-Op\" button should not be shown in Pip menu", uiDevice.findTvPipMenuElementWithDescription( - Components.PipActivity.MENU_ACTION_NO_OP)) - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_CLEAR) + ActivityOptions.Pip.MENU_ACTION_NO_OP)) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_CLEAR) ?: fail("\"Clear\" button should be shown in Pip menu") // ... as well as the "Full screen" and "Close" buttons. assertFullscreenAndCloseButtonsAreShown() - uiDevice.clickTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_CLEAR) + uiDevice.clickTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_CLEAR) // Invoking the "Clear" action should remove all the custom actions and their corresponding // buttons, ... uiDevice.waitUntilTvPipMenuElementWithDescriptionIsGone( - Components.PipActivity.MENU_ACTION_ON)?.also { + ActivityOptions.Pip.MENU_ACTION_ON)?.also { isGone -> if (!isGone) fail("\"On\" button should not be shown in Pip menu") } assertNull("\"Off\" button should not be shown in Pip menu", uiDevice.findTvPipMenuElementWithDescription( - Components.PipActivity.MENU_ACTION_OFF)) + ActivityOptions.Pip.MENU_ACTION_OFF)) assertNull("\"Clear\" button should not be shown in Pip menu", uiDevice.findTvPipMenuElementWithDescription( - Components.PipActivity.MENU_ACTION_CLEAR)) + ActivityOptions.Pip.MENU_ACTION_CLEAR)) assertNull("\"No-Op\" button should not be shown in Pip menu", uiDevice.findTvPipMenuElementWithDescription( - Components.PipActivity.MENU_ACTION_NO_OP)) + ActivityOptions.Pip.MENU_ACTION_NO_OP)) // ... but the menu should still contain the "Full screen" and "Close" buttons. assertFullscreenAndCloseButtonsAreShown() @@ -217,11 +217,11 @@ class TvPipMenuTests : TvPipTestBase() { enterPip_openMenu_assertShown() // PiP menu should contain "No-Op", "Off" and "Clear" buttons for the custom actions... - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_NO_OP) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_NO_OP) ?: fail("\"No-Op\" button should be shown in Pip menu") - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_OFF) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_OFF) ?: fail("\"Off\" button should be shown in Pip menu") - uiDevice.findTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_CLEAR) + uiDevice.findTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_CLEAR) ?: fail("\"Clear\" button should be shown in Pip menu") // ... should also contain the "Full screen" and "Close" buttons, ... assertFullscreenAndCloseButtonsAreShown() @@ -231,7 +231,7 @@ class TvPipMenuTests : TvPipTestBase() { assertNull("\"Pause\" button should not be shown in menu when there are custom actions", uiDevice.findTvPipMenuElementWithDescription(pauseButtonDescription)) - uiDevice.clickTvPipMenuElementWithDescription(Components.PipActivity.MENU_ACTION_CLEAR) + uiDevice.clickTvPipMenuElementWithDescription(ActivityOptions.Pip.MENU_ACTION_CLEAR) // Invoking the "Clear" action should remove all the custom actions, which should bring up // media buttons... uiDevice.waitForTvPipMenuElementWithDescription(pauseButtonDescription) @@ -244,7 +244,7 @@ class TvPipMenuTests : TvPipTestBase() { } private fun enterPip_openMenu_assertShown(): UiObject2 { - testApp.clickEnterPipButton() + testApp.clickEnterPipButton(wmHelper) // Pressing the Window key should bring up Pip menu uiDevice.pressWindowKey() return uiDevice.waitForTvPipMenu() ?: fail("Pip menu should have been shown") @@ -256,4 +256,4 @@ class TvPipMenuTests : TvPipTestBase() { uiDevice.findTvPipMenuFullscreenButton() ?: fail("\"Full screen\" button should be shown in Pip menu") } -}
\ No newline at end of file +} 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 bcf38d340867..134e97bd46e7 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 @@ -56,7 +56,7 @@ class TvPipNotificationTests : TvPipTestBase() { @Test fun pipNotification_postedAndDismissed() { testApp.launchViaIntent() - testApp.clickEnterPipButton() + testApp.clickEnterPipButton(wmHelper) assertNotNull("Pip notification should have been posted", waitForNotificationToAppear { it.isPipNotificationWithTitle(testApp.appName) }) @@ -70,7 +70,7 @@ class TvPipNotificationTests : TvPipTestBase() { @Test fun pipNotification_closeIntent() { testApp.launchViaIntent() - testApp.clickEnterPipButton() + testApp.clickEnterPipButton(wmHelper) val notification: StatusBarNotification = waitForNotificationToAppear { it.isPipNotificationWithTitle(testApp.appName) @@ -87,8 +87,8 @@ class TvPipNotificationTests : TvPipTestBase() { @Test fun pipNotification_menuIntent() { - testApp.launchViaIntent() - testApp.clickEnterPipButton() + testApp.launchViaIntent(wmHelper) + testApp.clickEnterPipButton(wmHelper) val notification: StatusBarNotification = waitForNotificationToAppear { it.isPipNotificationWithTitle(testApp.appName) @@ -106,10 +106,10 @@ class TvPipNotificationTests : TvPipTestBase() { @Test fun pipNotification_mediaSessionTitle_isDisplayed() { - testApp.launchViaIntent() + testApp.launchViaIntent(wmHelper) // Start media session and to PiP testApp.clickStartMediaSessionButton() - testApp.clickEnterPipButton() + testApp.clickEnterPipButton(wmHelper) // Wait for the correct notification to show up... waitForNotificationToAppear { @@ -170,4 +170,4 @@ private val StatusBarNotification.deleteIntent: PendingIntent? get() = tvExtensions?.getParcelable("delete_intent") private fun StatusBarNotification.isPipNotificationWithTitle(expectedTitle: String): Boolean = - tag == "TvPip" && title == expectedTitle
\ No newline at end of file + tag == "TvPip" && title == expectedTitle 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 9c3b0fa183b6..aeff0ac9f4f2 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 @@ -23,8 +23,8 @@ import android.os.SystemClock import android.view.Surface.ROTATION_0 import android.view.Surface.rotationToString import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME -import com.android.wm.shell.flicker.pip.PipTestBase import org.junit.After import org.junit.Assert.assertFalse import org.junit.Assume.assumeTrue @@ -33,6 +33,7 @@ import org.junit.Before abstract class TvPipTestBase : PipTestBase(rotationToString(ROTATION_0), ROTATION_0) { private val systemUiProcessObserver = SystemUiProcessObserver() + protected val wmHelper = WindowManagerStateHelper() @Before final override fun televisionSetUp() { @@ -88,4 +89,4 @@ abstract class TvPipTestBase : PipTestBase(rotationToString(ROTATION_0), ROTATIO companion object { private const val AFTER_TEXT_PROCESS_CHECK_DELAY = 1_000L // 1 sec } -}
\ No newline at end of file +} 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 new file mode 100644 index 000000000000..7dbd27949bdd --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt @@ -0,0 +1,177 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test copy content from the left to the right side of the split-screen. + * + * To run this test: `atest WMShellFlickerTests:CopyContentInSplit` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class CopyContentInSplit(testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + private val textEditApp = SplitScreenUtils.getIme(instrumentation) + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, textEditApp) + } + transitions { + SplitScreenUtils.copyContentInSplit( + instrumentation, device, primaryApp, textEditApp) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerKeepVisible() = testSpec.layerKeepVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerKeepVisible() = testSpec.layerKeepVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun textEditAppLayerKeepVisible() = testSpec.layerKeepVisible(textEditApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsKeepVisible() = testSpec.splitAppLayerBoundsKeepVisible( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun textEditAppBoundsKeepVisible() = testSpec.splitAppLayerBoundsKeepVisible( + textEditApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowKeepVisible() = testSpec.appWindowKeepVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun textEditAppWindowKeepVisible() = testSpec.appWindowKeepVisible(textEditApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 new file mode 100644 index 000000000000..3646fd7f0177 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt @@ -0,0 +1,205 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.WindowUtils +import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test dismiss split screen by dragging the divider bar. + * + * To run this test: `atest WMShellFlickerTests:DismissSplitScreenByDivider` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class DismissSplitScreenByDivider (testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + } + transitions { + if (tapl.isTablet) { + SplitScreenUtils.dragDividerToDismissSplit(device, wmHelper, + dragToRight = false, dragToBottom = true) + } else { + SplitScreenUtils.dragDividerToDismissSplit(device, wmHelper, + dragToRight = true, dragToBottom = true) + } + wmHelper.StateSyncBuilder() + .withFullScreenApp(secondaryApp) + .waitForAndVerify() + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerBecomesInvisible() = testSpec.splitScreenDividerBecomesInvisible() + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsBecomesInvisible() = testSpec.splitAppLayerBoundsBecomesInvisible( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsIsFullscreenAtEnd() { + testSpec.assertLayers { + this.isVisible(secondaryApp) + .isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + .then() + .isInvisible(secondaryApp) + .isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + .then() + .isVisible(secondaryApp, isOptional = true) + .isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT, isOptional = true) + .then() + .contains(SPLIT_SCREEN_DIVIDER_COMPONENT) + .then() + .invoke("secondaryAppBoundsIsFullscreenAtEnd") { + val displayBounds = WindowUtils.getDisplayBounds(testSpec.endRotation) + it.visibleRegion(secondaryApp).coversExactly(displayBounds) + } + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowBecomesInvisible() = testSpec.appWindowBecomesInvisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 new file mode 100644 index 000000000000..80abedd476e6 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt @@ -0,0 +1,181 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test dismiss split screen by go home. + * + * To run this test: `atest WMShellFlickerTests:DismissSplitScreenByGoHome` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class DismissSplitScreenByGoHome( + testSpec: FlickerTestParameter +) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + } + transitions { + tapl.goHome() + wmHelper.StateSyncBuilder() + .withHomeActivityVisible() + .waitForAndVerify() + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerBecomesInvisible() = testSpec.splitScreenDividerBecomesInvisible() + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(primaryApp) + + // TODO(b/245472831): Move back to presubmit after shell transitions landing. + @FlakyTest(bugId = 245472831) + @Test + fun secondaryAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(primaryApp) + + // TODO(b/245472831): Move back to presubmit after shell transitions landing. + @FlakyTest(bugId = 245472831) + @Test + fun primaryAppBoundsBecomesInvisible() = testSpec.splitAppLayerBoundsBecomesInvisible( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsBecomesInvisible() = testSpec.splitAppLayerBoundsBecomesInvisible( + secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowBecomesInvisible() = testSpec.appWindowBecomesInvisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowBecomesInvisible() = testSpec.appWindowBecomesInvisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 new file mode 100644 index 000000000000..2915787d5a43 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt @@ -0,0 +1,185 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.Surface +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test resize split by dragging the divider bar. + * + * To run this test: `atest WMShellFlickerTests:DragDividerToResize` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class DragDividerToResize (testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + } + transitions { + SplitScreenUtils.dragDividerToResizeAndWait(device, wmHelper) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerKeepVisible() = testSpec.layerKeepVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerKeepVisible() = testSpec.layerKeepVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerVisibilityChanges() { + testSpec.assertLayers { + this.isVisible(secondaryApp) + .then() + .isInvisible(secondaryApp) + .then() + .isVisible(secondaryApp) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowKeepVisible() = testSpec.appWindowKeepVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowKeepVisible() = testSpec.appWindowKeepVisible(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsChanges() = testSpec.splitAppLayerBoundsChanges( + primaryApp, landscapePosLeft = true, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsChanges() = testSpec.splitAppLayerBoundsChanges( + secondaryApp, landscapePosLeft = false, portraitPosTop = true) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + supportedRotations = listOf(Surface.ROTATION_0), + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 702710caded7..8e041a703802 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 @@ -16,6 +16,8 @@ package com.android.wm.shell.flicker.splitscreen +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.view.WindowManagerPolicyConstants import androidx.test.filters.RequiresDevice @@ -24,12 +26,13 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group1 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled +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.helpers.SplitScreenHelper 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.splitAppLayerBoundsBecomesVisibleByDrag import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import org.junit.Assume @@ -56,65 +59,167 @@ class EnterSplitScreenByDragFromAllApps( ) : SplitScreenBase(testSpec) { @Before - open fun before() { - Assume.assumeTrue(taplInstrumentation.isTablet) + fun before() { + Assume.assumeTrue(tapl.isTablet) } override val transition: FlickerBuilder.() -> Unit get() = { super.transition(this) setup { - eachRun { - taplInstrumentation.goHome() - primaryApp.launchViaIntent(wmHelper) - } + tapl.goHome() + primaryApp.launchViaIntent(wmHelper) } transitions { - taplInstrumentation.launchedAppState.taskbar - .openAllApps() - .getAppIcon(secondaryApp.appName) - .dragToSplitscreen(secondaryApp.component.packageName, - primaryApp.component.packageName) + tapl.launchedAppState.taskbar + .openAllApps() + .getAppIcon(secondaryApp.appName) + .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`) + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) } } + @IwTest(focusArea = "sysui") @Presubmit @Test - fun dividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + fun splitScreenDividerBecomesVisible() { + Assume.assumeFalse(isShellTransitionsEnabled) + testSpec.splitScreenDividerBecomesVisible() + } + // TODO(b/245472831): Back to splitScreenDividerBecomesVisible after shell transition ready. + @IwTest(focusArea = "sysui") @Presubmit @Test - fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component) + fun splitScreenDividerIsVisibleAtEnd_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + testSpec.assertLayersEnd { + this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + } + } + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component) + fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp) + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() { + Assume.assumeFalse(isShellTransitionsEnabled) + testSpec.assertLayers { + this.isInvisible(secondaryApp) + .then() + .isVisible(secondaryApp) + .then() + .isInvisible(secondaryApp) + .then() + .isVisible(secondaryApp) + } + } + + // TODO(b/245472831): Align to legacy transition after shell transition ready. + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + testSpec.layerBecomesVisible(secondaryApp) + } + + @IwTest(focusArea = "sysui") @Presubmit @Test fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( - testSpec.endRotation, primaryApp.component, false /* splitLeftTop */) + primaryApp, landscapePosLeft = false, portraitPosTop = false) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible( - testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */) + fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisibleByDrag( + secondaryApp) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component) + fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppWindowBecomesVisible() = - testSpec.appWindowBecomesVisible(secondaryApp.component) + fun secondaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) 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 7323d992ecd4..2ee12f1f0af2 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 @@ -16,21 +16,22 @@ package com.android.wm.shell.flicker.splitscreen +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.view.WindowManagerPolicyConstants import androidx.test.filters.RequiresDevice -import androidx.test.uiautomator.By -import androidx.test.uiautomator.Until import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group1 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled +import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.helpers.SplitScreenHelper 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.splitAppLayerBoundsBecomesVisibleByDrag import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import org.junit.Assume @@ -56,80 +57,174 @@ class EnterSplitScreenByDragFromNotification( testSpec: FlickerTestParameter ) : SplitScreenBase(testSpec) { - private val sendNotificationApp = SplitScreenHelper.getSendNotification(instrumentation) + private val sendNotificationApp = SplitScreenUtils.getSendNotification(instrumentation) @Before fun before() { - Assume.assumeTrue(taplInstrumentation.isTablet) + Assume.assumeTrue(tapl.isTablet) } + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = { super.transition(this) setup { - eachRun { - // Send a notification - sendNotificationApp.launchViaIntent(wmHelper) - val sendNotification = device.wait( - Until.findObject(By.text("Send Notification")), - SplitScreenHelper.TIMEOUT_MS - ) - sendNotification?.click() ?: error("Send notification button not found") - - taplInstrumentation.goHome() - primaryApp.launchViaIntent(wmHelper) - } + // Send a notification + sendNotificationApp.launchViaIntent(wmHelper) + sendNotificationApp.postNotification(wmHelper) + tapl.goHome() + primaryApp.launchViaIntent(wmHelper) } transitions { - SplitScreenHelper.dragFromNotificationToSplit(instrumentation, device, wmHelper) + SplitScreenUtils.dragFromNotificationToSplit(instrumentation, device, wmHelper) + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, sendNotificationApp) } teardown { - eachRun { - sendNotificationApp.exit(wmHelper) - } + sendNotificationApp.exit(wmHelper) } } + @IwTest(focusArea = "sysui") @Presubmit @Test - fun dividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + fun splitScreenDividerBecomesVisible() { + Assume.assumeFalse(isShellTransitionsEnabled) + testSpec.splitScreenDividerBecomesVisible() + } + // TODO(b/245472831): Back to splitScreenDividerBecomesVisible after shell transition ready. + @IwTest(focusArea = "sysui") @Presubmit @Test - fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component) + fun splitScreenDividerIsVisibleAtEnd_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + testSpec.assertLayersEnd { + this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + } + } + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppLayerBecomesVisible() = - testSpec.layerBecomesVisible(sendNotificationApp.component) + fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp) + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() { + Assume.assumeFalse(isShellTransitionsEnabled) + testSpec.assertLayers { + this.isInvisible(sendNotificationApp) + .then() + .isVisible(sendNotificationApp) + .then() + .isInvisible(sendNotificationApp) + .then() + .isVisible(sendNotificationApp) + } + } + + // TODO(b/245472831): Align to legacy transition after shell transition ready. + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + testSpec.layerBecomesVisible(sendNotificationApp) + } + + @IwTest(focusArea = "sysui") @Presubmit @Test fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( - testSpec.endRotation, primaryApp.component, false /* splitLeftTop */ - ) + primaryApp, landscapePosLeft = false, portraitPosTop = false) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible( - testSpec.endRotation, sendNotificationApp.component, true /* splitLeftTop */ - ) + fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisibleByDrag( + sendNotificationApp) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component) + fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppWindowIsVisibleAtEnd() = - testSpec.appWindowIsVisibleAtEnd(sendNotificationApp.component) + fun secondaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(sendNotificationApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) 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 05c6e24ee89d..a11874e00228 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 @@ -16,6 +16,8 @@ package com.android.wm.shell.flicker.splitscreen +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import android.view.WindowManagerPolicyConstants import androidx.test.filters.RequiresDevice @@ -24,12 +26,13 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group1 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled +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.helpers.SplitScreenHelper 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.splitAppLayerBoundsBecomesVisibleByDrag import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import org.junit.Assume @@ -57,70 +60,169 @@ class EnterSplitScreenByDragFromTaskbar( @Before fun before() { - Assume.assumeTrue(taplInstrumentation.isTablet) + Assume.assumeTrue(tapl.isTablet) } + /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = { super.transition(this) setup { - eachRun { - taplInstrumentation.goHome() - SplitScreenHelper.createShortcutOnHotseatIfNotExist( - taplInstrumentation, secondaryApp.appName - ) - primaryApp.launchViaIntent(wmHelper) - } + tapl.goHome() + SplitScreenUtils.createShortcutOnHotseatIfNotExist( + tapl, secondaryApp.appName + ) + primaryApp.launchViaIntent(wmHelper) } transitions { - taplInstrumentation.launchedAppState.taskbar + tapl.launchedAppState.taskbar .getAppIcon(secondaryApp.appName) - .dragToSplitscreen( - secondaryApp.component.packageName, - primaryApp.component.packageName - ) + .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`) + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) } } + @IwTest(focusArea = "sysui") @Presubmit @Test - fun dividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + fun splitScreenDividerBecomesVisible() { + Assume.assumeFalse(isShellTransitionsEnabled) + testSpec.splitScreenDividerBecomesVisible() + } + // TODO(b/245472831): Back to splitScreenDividerBecomesVisible after shell transition ready. + @IwTest(focusArea = "sysui") @Presubmit @Test - fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component) + fun splitScreenDividerIsVisibleAtEnd_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + testSpec.assertLayersEnd { + this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + } + } + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component) + fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp) + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() { + Assume.assumeFalse(isShellTransitionsEnabled) + testSpec.assertLayers { + this.isInvisible(secondaryApp) + .then() + .isVisible(secondaryApp) + .then() + .isInvisible(secondaryApp) + .then() + .isVisible(secondaryApp) + } + } + + // TODO(b/245472831): Align to legacy transition after shell transition ready. + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible_ShellTransit() { + Assume.assumeTrue(isShellTransitionsEnabled) + testSpec.layerBecomesVisible(secondaryApp) + } + + @IwTest(focusArea = "sysui") @Presubmit @Test fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( - testSpec.endRotation, primaryApp.component, false /* splitLeftTop */ - ) + primaryApp, landscapePosLeft = false, portraitPosTop = false) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible( - testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */ - ) + fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisibleByDrag( + secondaryApp) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component) + fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp) + @IwTest(focusArea = "sysui") @Presubmit @Test - fun secondaryAppWindowBecomesVisible() = - testSpec.appWindowBecomesVisible(secondaryApp.component) + fun secondaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) ) 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 new file mode 100644 index 000000000000..6064b52938c8 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt @@ -0,0 +1,181 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test enter split screen from Overview. + * + * To run this test: `atest WMShellFlickerTests:EnterSplitScreenFromOverview` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class EnterSplitScreenFromOverview(testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + tapl.workspace.switchToOverview().dismissAllTasks() + primaryApp.launchViaIntent(wmHelper) + secondaryApp.launchViaIntent(wmHelper) + tapl.goHome() + wmHelper.StateSyncBuilder() + .withAppTransitionIdle() + .withHomeActivityVisible() + .waitForAndVerify() + } + transitions { + SplitScreenUtils.splitFromOverview(tapl) + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible( + secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests() + } + } +} 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/SplitScreenBase.kt index 52c2daf96a3c..e6d6379e750c 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/SplitScreenBase.kt @@ -16,44 +16,28 @@ package com.android.wm.shell.flicker.splitscreen -import android.app.Instrumentation import android.content.Context -import androidx.test.platform.app.InstrumentationRegistry -import com.android.launcher3.tapl.LauncherInstrumentation -import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.setRotation -import com.android.wm.shell.flicker.helpers.SplitScreenHelper +import com.android.wm.shell.flicker.BaseTest -abstract class SplitScreenBase(protected val testSpec: FlickerTestParameter) { - protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() - protected val taplInstrumentation = LauncherInstrumentation() +abstract class SplitScreenBase(testSpec: FlickerTestParameter) : BaseTest(testSpec) { protected val context: Context = instrumentation.context - protected val primaryApp = SplitScreenHelper.getPrimary(instrumentation) - protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation) + protected val primaryApp = SplitScreenUtils.getPrimary(instrumentation) + protected val secondaryApp = SplitScreenUtils.getSecondary(instrumentation) - @FlickerBuilderProvider - fun buildFlicker(): FlickerBuilder { - return FlickerBuilder(instrumentation).apply { - transition(this) - } - } - - protected open val transition: FlickerBuilder.() -> Unit + /** {@inheritDoc} */ + override val transition: FlickerBuilder.() -> Unit get() = { setup { - test { - taplInstrumentation.setEnableRotation(true) - setRotation(testSpec.startRotation) - taplInstrumentation.setExpectedRotation(testSpec.startRotation) - } + tapl.setEnableRotation(true) + setRotation(testSpec.startRotation) + tapl.setExpectedRotation(testSpec.startRotation) } teardown { - eachRun { - primaryApp.exit(wmHelper) - secondaryApp.exit(wmHelper) - } + primaryApp.exit(wmHelper) + secondaryApp.exit(wmHelper) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt new file mode 100644 index 000000000000..e57ac91617b7 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt @@ -0,0 +1,341 @@ +/* + * 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.splitscreen + +import android.app.Instrumentation +import android.graphics.Point +import android.os.SystemClock +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.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.helpers.StandardAppHelper +import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.server.wm.traces.common.ComponentNameMatcher +import com.android.server.wm.traces.common.IComponentMatcher +import com.android.server.wm.traces.common.IComponentNameMatcher +import com.android.server.wm.traces.parser.toFlickerComponent +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper +import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME + +internal 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 GESTURE_STEP_MS = 16L + private const val LONG_PRESS_TIME_MS = 100L + 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) + + 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, + primaryApp: StandardAppHelper, + secondaryApp: StandardAppHelper + ) { + tapl.workspace.switchToOverview().dismissAllTasks() + primaryApp.launchViaIntent(wmHelper) + secondaryApp.launchViaIntent(wmHelper) + tapl.goHome() + wmHelper.StateSyncBuilder() + .withHomeActivityVisible() + .waitForAndVerify() + splitFromOverview(tapl) + waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + + fun splitFromOverview(tapl: LauncherInstrumentation) { + // 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.workspace.switchToOverview().overviewActions + .clickSplit() + .currentTask + .open() + } else { + tapl.workspace.switchToOverview().currentTask + .tapMenu() + .tapSplitMenuItem() + .currentTask + .open() + } + SystemClock.sleep(TIMEOUT_MS) + } + + 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 longPress( + instrumentation: Instrumentation, + point: Point + ) { + val downTime = SystemClock.uptimeMillis() + touch(instrumentation, MotionEvent.ACTION_DOWN, downTime, downTime, TIMEOUT_MS, point) + SystemClock.sleep(LONG_PRESS_TIME_MS) + touch(instrumentation, MotionEvent.ACTION_UP, downTime, downTime, TIMEOUT_MS, point) + } + + 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)) + + 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) + longPress(instrumentation, textView.visibleCenter) + + val copyBtn = device.wait(Until.findObject(By.text("Copy")), TIMEOUT_MS) + copyBtn.click() + + // Paste text to destinationApp + val editText = device.wait(Until.findObject( + By.res(destinationApp.packageName, "plain_text_input")), TIMEOUT_MS) + longPress(instrumentation, editText.visibleCenter) + + val pasteBtn = device.wait(Until.findObject(By.text("Paste")), TIMEOUT_MS) + 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/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt new file mode 100644 index 000000000000..f06dd66f61d2 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt @@ -0,0 +1,225 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.FlakyTest +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.isRotated +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test double tap the divider bar to switch the two apps. + * + * To run this test: `atest WMShellFlickerTests:SwitchAppByDoubleTapDivider` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class SwitchAppByDoubleTapDivider(testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + } + transitions { + SplitScreenUtils.doubleTapDividerToSwitch(device) + wmHelper.StateSyncBuilder() + .withAppTransitionIdle() + .waitForAndVerify() + + waitForLayersToSwitch(wmHelper) + waitForWindowsToSwitch(wmHelper) + } + } + + private fun waitForWindowsToSwitch(wmHelper: WindowManagerStateHelper) { + wmHelper.StateSyncBuilder().add("appWindowsSwitched") { + val primaryAppWindow = it.wmState.visibleWindows.firstOrNull { window -> + primaryApp.windowMatchesAnyOf(window) + } ?: return@add false + val secondaryAppWindow = it.wmState.visibleWindows.firstOrNull { window -> + secondaryApp.windowMatchesAnyOf(window) + } ?: return@add false + + if (testSpec.startRotation.isRotated()) { + return@add primaryAppWindow.frame.right <= secondaryAppWindow.frame.left + } else { + return@add primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top + } + }.waitForAndVerify() + } + + private fun waitForLayersToSwitch(wmHelper: WindowManagerStateHelper) { + wmHelper.StateSyncBuilder().add("appLayersSwitched") { + val primaryAppLayer = it.layerState.visibleLayers.firstOrNull { window -> + primaryApp.layerMatchesAnyOf(window) + } ?: return@add false + val secondaryAppLayer = it.layerState.visibleLayers.firstOrNull { window -> + secondaryApp.layerMatchesAnyOf(window) + } ?: return@add false + + val primaryVisibleRegion = primaryAppLayer.visibleRegion?.bounds + ?: return@add false + val secondaryVisibleRegion = secondaryAppLayer.visibleRegion?.bounds + ?: return@add false + + if (testSpec.startRotation.isRotated()) { + return@add primaryVisibleRegion.right <= secondaryVisibleRegion.left + } else { + return@add primaryVisibleRegion.bottom <= secondaryVisibleRegion.top + } + }.waitForAndVerify() + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerKeepVisible() = testSpec.layerKeepVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + primaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + // TODO(b/246490534): Move back to presubmit after withAppTransitionIdle is robust enough to + // get the correct end state. + @FlakyTest(bugId = 246490534) + @Test + fun secondaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + secondaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 new file mode 100644 index 000000000000..5c3011643270 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt @@ -0,0 +1,182 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 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 to split pair from another app. + * + * To run this test: `atest WMShellFlickerTests:SwitchBackToSplitFromAnotherApp` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class SwitchBackToSplitFromAnotherApp(testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + val thirdApp = SplitScreenUtils.getNonResizeable(instrumentation) + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + + thirdApp.launchViaIntent(wmHelper) + wmHelper.StateSyncBuilder() + .withWindowSurfaceAppeared(thirdApp) + .waitForAndVerify() + } + transitions { + tapl.launchedAppState.quickSwitchToPreviousApp() + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 new file mode 100644 index 000000000000..9c66a3734da3 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt @@ -0,0 +1,181 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 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 to split pair from home. + * + * To run this test: `atest WMShellFlickerTests:SwitchBackToSplitFromHome` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class SwitchBackToSplitFromHome(testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + + tapl.goHome() + wmHelper.StateSyncBuilder() + .withHomeActivityVisible() + .waitForAndVerify() + } + transitions { + tapl.workspace.quickSwitchToPreviousApp() + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} 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 new file mode 100644 index 000000000000..e8862bd4c982 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt @@ -0,0 +1,183 @@ +/* + * 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.splitscreen + +import android.platform.test.annotations.IwTest +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +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 org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test switch back to split pair from recent. + * + * To run this test: `atest WMShellFlickerTests:SwitchBackToSplitFromRecent` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class SwitchBackToSplitFromRecent(testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + SplitScreenUtils.enterSplit(wmHelper, tapl, primaryApp, secondaryApp) + + tapl.goHome() + wmHelper.StateSyncBuilder() + .withHomeActivityVisible() + .waitForAndVerify() + } + transitions { + tapl.workspace.switchToOverview() + .currentTask + .open() + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + } + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun splitScreenDividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible() + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( + secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun primaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(primaryApp) + + @IwTest(focusArea = "sysui") + @Presubmit + @Test + fun secondaryAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp deleted file mode 100644 index ea606df1536d..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2020 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "WMShellFlickerTestApp", - srcs: ["**/*.java"], - sdk_version: "current", - test_suites: ["device-tests"], -} - -java_library { - name: "wmshell-flicker-test-components", - srcs: ["src/**/Components.java"], - sdk_version: "test_current", -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml deleted file mode 100644 index bc0b0b6292b4..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml +++ /dev/null @@ -1,147 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.wm.shell.flicker.testapp"> - - <uses-sdk android:minSdkVersion="29" - android:targetSdkVersion="29"/> - <application android:allowBackup="false" - android:supportsRtl="true"> - <activity android:name=".FixedActivity" - android:resizeableActivity="true" - android:supportsPictureInPicture="true" - android:launchMode="singleTop" - android:theme="@style/CutoutShortEdges" - android:label="FixedApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <activity android:name=".PipActivity" - android:resizeableActivity="true" - android:supportsPictureInPicture="true" - android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" - android:taskAffinity="com.android.wm.shell.flicker.testapp.PipActivity" - android:theme="@style/CutoutShortEdges" - android:launchMode="singleTop" - android:label="PipApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LEANBACK_LAUNCHER"/> - </intent-filter> - </activity> - - <activity android:name=".ImeActivity" - android:taskAffinity="com.android.wm.shell.flicker.testapp.ImeActivity" - android:theme="@style/CutoutShortEdges" - android:label="ImeApp" - android:launchMode="singleTop" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LEANBACK_LAUNCHER"/> - </intent-filter> - </activity> - - <activity android:name=".SplitScreenActivity" - android:resizeableActivity="true" - android:taskAffinity="com.android.wm.shell.flicker.testapp.SplitScreenActivity" - android:theme="@style/CutoutShortEdges" - android:label="SplitScreenPrimaryApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - - <activity android:name=".SplitScreenSecondaryActivity" - android:resizeableActivity="true" - android:taskAffinity="com.android.wm.shell.flicker.testapp.SplitScreenSecondaryActivity" - android:theme="@style/CutoutShortEdges" - android:label="SplitScreenSecondaryApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - - <activity android:name=".SendNotificationActivity" - android:taskAffinity="com.android.wm.shell.flicker.testapp.SendNotificationActivity" - android:theme="@style/CutoutShortEdges" - android:label="SendNotificationApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - - <activity android:name=".NonResizeableActivity" - android:resizeableActivity="false" - android:taskAffinity="com.android.wm.shell.flicker.testapp.NonResizeableActivity" - android:theme="@style/CutoutShortEdges" - android:label="NonResizeableApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - - <activity android:name=".SimpleActivity" - android:taskAffinity="com.android.wm.shell.flicker.testapp.SimpleActivity" - android:theme="@style/CutoutShortEdges" - android:label="SimpleApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <activity - android:name=".LaunchBubbleActivity" - android:label="LaunchBubbleApp" - android:exported="true" - android:theme="@style/CutoutShortEdges" - android:launchMode="singleTop"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - <activity - android:name=".BubbleActivity" - android:label="BubbleApp" - android:exported="false" - android:theme="@style/CutoutShortEdges" - android:resizeableActivity="true" /> - </application> -</manifest> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/bg.png b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/bg.png Binary files differdeleted file mode 100644 index d424a17b4157..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/bg.png +++ /dev/null diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/ic_bubble.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/ic_bubble.xml deleted file mode 100644 index b43f31da748d..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/ic_bubble.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2021 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M7.2,14.4m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/> - <path - android:fillColor="#FF000000" - android:pathData="M14.8,18m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/> - <path - android:fillColor="#FF000000" - android:pathData="M15.2,8.8m-4.8,0a4.8,4.8 0,1 1,9.6 0a4.8,4.8 0,1 1,-9.6 0"/> -</vector> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/ic_message.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/ic_message.xml deleted file mode 100644 index 0e8c7a0fe64a..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/drawable/ic_message.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2021 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:pathData="M12,4c-4.97,0 -9,3.58 -9,8c0,1.53 0.49,2.97 1.33,4.18c0.12,0.18 0.2,0.46 0.1,0.66c-0.33,0.68 -0.79,1.52 -1.38,2.39c-0.12,0.17 0.01,0.41 0.21,0.39c0.63,-0.05 1.86,-0.26 3.38,-0.91c0.17,-0.07 0.36,-0.06 0.52,0.03C8.55,19.54 10.21,20 12,20c4.97,0 9,-3.58 9,-8S16.97,4 12,4zM16.94,11.63l-3.29,3.29c-0.13,0.13 -0.34,0.04 -0.34,-0.14v-1.57c0,-0.11 -0.1,-0.21 -0.21,-0.2c-2.19,0.06 -3.65,0.65 -5.14,1.95c-0.15,0.13 -0.38,0 -0.33,-0.19c0.7,-2.57 2.9,-4.57 5.5,-4.75c0.1,-0.01 0.18,-0.09 0.18,-0.19V8.2c0,-0.18 0.22,-0.27 0.34,-0.14l3.29,3.29C17.02,11.43 17.02,11.55 16.94,11.63z" - android:fillColor="#000000" - android:fillType="evenOdd"/> -</vector> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_bubble.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_bubble.xml deleted file mode 100644 index f8b0ca3da26e..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_bubble.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2021 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <Button - android:id="@+id/button_finish" - android:layout_width="wrap_content" - android:layout_height="48dp" - android:layout_marginStart="8dp" - android:text="Finish" /> - <Button - android:id="@+id/button_new_task" - android:layout_width="wrap_content" - android:layout_height="46dp" - android:layout_marginStart="8dp" - android:text="New Task" /> - <Button - android:id="@+id/button_new_bubble" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:text="New Bubble" /> - - <Button - android:id="@+id/button_activity_for_result" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginStart="8dp" - android:text="Activity For Result" /> -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml deleted file mode 100644 index 4708cfd48381..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2018 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:focusableInTouchMode="true" - android:background="@android:color/holo_green_light"> - <EditText android:id="@+id/plain_text_input" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:inputType="text"/> -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_main.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_main.xml deleted file mode 100644 index f23c46455c63..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_main.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2021 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:background="@android:color/black"> - - <Button - android:id="@+id/button_create" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerHorizontal="true" - android:layout_centerVertical="true" - android:text="Add Bubble" /> - - <Button - android:id="@+id/button_cancel" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_below="@id/button_create" - android:layout_centerHorizontal="true" - android:layout_marginTop="20dp" - android:text="Cancel Bubble" /> - - <Button - android:id="@+id/button_cancel_all" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_below="@id/button_cancel" - android:layout_centerHorizontal="true" - android:layout_marginTop="20dp" - android:text="Cancel All Bubble" /> -</RelativeLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml deleted file mode 100644 index 45d5917f86d6..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?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. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:background="@android:color/holo_orange_light"> - - <TextView - android:id="@+id/NonResizeableTest" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:gravity="center_vertical|center_horizontal" - android:text="NonResizeableActivity" - android:textAppearance="?android:attr/textAppearanceLarge"/> - -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_notification.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_notification.xml deleted file mode 100644 index 8d59b567e59b..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_notification.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2021 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:background="@android:color/black"> - - <Button - android:id="@+id/button_send_notification" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerHorizontal="true" - android:layout_centerVertical="true" - android:text="Send Notification" /> -</RelativeLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml deleted file mode 100644 index 229098313afa..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml +++ /dev/null @@ -1,141 +0,0 @@ -<?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. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:background="@android:color/holo_blue_bright"> - - <!-- All the buttons (and other clickable elements) should be arranged in a way so that it is - possible to "cycle" over all them by clicking on the D-Pad DOWN button. The way we do it - here is by arranging them this vertical LL and by relying on the nextFocusDown attribute - where things are arranged differently and to circle back up to the top once we reach the - bottom. --> - - <Button - android:id="@+id/enter_pip" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Enter PIP" - android:onClick="enterPip"/> - - <CheckBox - android:id="@+id/with_custom_actions" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="With custom actions"/> - - <RadioGroup - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:checkedButton="@id/enter_pip_on_leave_disabled"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Enter PiP on home press"/> - - <RadioButton - android:id="@+id/enter_pip_on_leave_disabled" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Disabled" - android:onClick="onAutoPipSelected"/> - - <RadioButton - android:id="@+id/enter_pip_on_leave_manual" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Via code behind" - android:onClick="onAutoPipSelected"/> - - <RadioButton - android:id="@+id/enter_pip_on_leave_autoenter" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Auto-enter PiP" - android:onClick="onAutoPipSelected"/> - </RadioGroup> - - <RadioGroup - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:checkedButton="@id/ratio_default"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Ratio"/> - - <RadioButton - android:id="@+id/ratio_default" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Default" - android:onClick="onRatioSelected"/> - - <RadioButton - android:id="@+id/ratio_square" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Square [1:1]" - android:onClick="onRatioSelected"/> - - <RadioButton - android:id="@+id/ratio_wide" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Wide [2:1]" - android:onClick="onRatioSelected"/> - - <RadioButton - android:id="@+id/ratio_tall" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Tall [1:2]" - android:onClick="onRatioSelected"/> - </RadioGroup> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Media Session"/> - - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content"> - - <Button - android:id="@+id/media_session_start" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:nextFocusDown="@id/media_session_stop" - android:text="Start"/> - - <Button - android:id="@+id/media_session_stop" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:nextFocusDown="@id/enter_pip" - android:text="Stop"/> - - </LinearLayout> - -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_simple.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_simple.xml deleted file mode 100644 index 5d94e5177dcc..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_simple.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2018 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@android:color/holo_orange_light"> - -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_splitscreen.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_splitscreen.xml deleted file mode 100644 index 84789f5a6c02..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_splitscreen.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?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. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:background="@android:color/holo_green_light"> - - <TextView - android:id="@+id/SplitScreenTest" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:gravity="center_vertical|center_horizontal" - android:text="PrimaryActivity" - android:textAppearance="?android:attr/textAppearanceLarge"/> - -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml deleted file mode 100644 index 674bb70ad01e..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_splitscreen_secondary.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?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. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:background="@android:color/holo_blue_light"> - - <TextView - android:id="@+id/SplitScreenTest" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:gravity="center_vertical|center_horizontal" - android:text="SecondaryActivity" - android:textAppearance="?android:attr/textAppearanceLarge"/> - -</LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/values/styles.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/values/styles.xml deleted file mode 100644 index 23b51cc06f04..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/values/styles.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2022 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> - -<resources> - <style name="DefaultTheme" parent="@android:style/Theme.DeviceDefault"> - <item name="android:windowBackground">@android:color/darker_gray</item> - </style> - - <style name="CutoutDefault" parent="@style/DefaultTheme"> - <item name="android:windowLayoutInDisplayCutoutMode">default</item> - </style> - - <style name="CutoutShortEdges" parent="@style/DefaultTheme"> - <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> - </style> - - <style name="CutoutNever" parent="@style/DefaultTheme"> - <item name="android:windowLayoutInDisplayCutoutMode">never</item> - </style> -</resources>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleActivity.java deleted file mode 100644 index bc3bc75ab903..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleActivity.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.widget.Toast; - -public class BubbleActivity extends Activity { - private int mNotifId = 0; - - public BubbleActivity() { - super(); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - if (intent != null) { - mNotifId = intent.getIntExtra(BubbleHelper.EXTRA_BUBBLE_NOTIF_ID, -1); - } else { - mNotifId = -1; - } - - setContentView(R.layout.activity_bubble); - } - - @Override - protected void onStart() { - super.onStart(); - } - - @Override - protected void onResume() { - super.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - } - - @Override - protected void onStop() { - super.onStop(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - String result = resultCode == Activity.RESULT_OK ? "OK" : "CANCELLED"; - Toast.makeText(this, "Activity result: " + result, Toast.LENGTH_SHORT).show(); - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java deleted file mode 100644 index 6cd93eff2803..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Person; -import android.content.Context; -import android.content.Intent; -import android.graphics.Point; -import android.graphics.drawable.Icon; -import android.os.SystemClock; -import android.service.notification.StatusBarNotification; -import android.view.WindowManager; - -import java.util.HashMap; - -public class BubbleHelper { - - static final String EXTRA_BUBBLE_NOTIF_ID = "EXTRA_BUBBLE_NOTIF_ID"; - static final String CHANNEL_ID = "bubbles"; - static final String CHANNEL_NAME = "Bubbles"; - static final int DEFAULT_HEIGHT_DP = 300; - - private static BubbleHelper sInstance; - - private final Context mContext; - private NotificationManager mNotificationManager; - private float mDisplayHeight; - - private HashMap<Integer, BubbleInfo> mBubbleMap = new HashMap<>(); - - private int mNextNotifyId = 0; - private int mColourIndex = 0; - - public static class BubbleInfo { - public int id; - public int height; - public Icon icon; - - public BubbleInfo(int id, int height, Icon icon) { - this.id = id; - this.height = height; - this.icon = icon; - } - } - - public static BubbleHelper getInstance(Context context) { - if (sInstance == null) { - sInstance = new BubbleHelper(context); - } - return sInstance; - } - - private BubbleHelper(Context context) { - mContext = context; - mNotificationManager = context.getSystemService(NotificationManager.class); - - NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, - NotificationManager.IMPORTANCE_DEFAULT); - channel.setDescription("Channel that posts bubbles"); - channel.setAllowBubbles(true); - mNotificationManager.createNotificationChannel(channel); - - Point p = new Point(); - WindowManager wm = context.getSystemService(WindowManager.class); - wm.getDefaultDisplay().getRealSize(p); - mDisplayHeight = p.y; - - } - - private int getNextNotifyId() { - int id = mNextNotifyId; - mNextNotifyId++; - return id; - } - - private Icon getIcon() { - return Icon.createWithResource(mContext, R.drawable.bg); - } - - public int addNewBubble(boolean autoExpand, boolean suppressNotif) { - int id = getNextNotifyId(); - BubbleInfo info = new BubbleInfo(id, DEFAULT_HEIGHT_DP, getIcon()); - mBubbleMap.put(info.id, info); - - Notification.BubbleMetadata data = getBubbleBuilder(info) - .setSuppressNotification(suppressNotif) - .setAutoExpandBubble(false) - .build(); - Notification notification = getNotificationBuilder(info.id) - .setBubbleMetadata(data).build(); - - mNotificationManager.notify(info.id, notification); - return info.id; - } - - private Notification.Builder getNotificationBuilder(int id) { - Person chatBot = new Person.Builder() - .setBot(true) - .setName("BubbleChat") - .setImportant(true) - .build(); - String shortcutId = "BubbleChat"; - return new Notification.Builder(mContext, CHANNEL_ID) - .setChannelId(CHANNEL_ID) - .setShortcutId(shortcutId) - .setContentTitle("BubbleChat") - .setContentIntent(PendingIntent.getActivity(mContext, 0, - new Intent(mContext, LaunchBubbleActivity.class), - PendingIntent.FLAG_UPDATE_CURRENT)) - .setStyle(new Notification.MessagingStyle(chatBot) - .setConversationTitle("BubbleChat") - .addMessage("BubbleChat", - SystemClock.currentThreadTimeMillis() - 300000, chatBot) - .addMessage("Is it me, " + id + ", you're looking for?", - SystemClock.currentThreadTimeMillis(), chatBot) - ) - .setSmallIcon(R.drawable.ic_bubble); - } - - private Notification.BubbleMetadata.Builder getBubbleBuilder(BubbleInfo info) { - Intent target = new Intent(mContext, BubbleActivity.class); - target.putExtra(EXTRA_BUBBLE_NOTIF_ID, info.id); - PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, info.id, target, - PendingIntent.FLAG_UPDATE_CURRENT); - - return new Notification.BubbleMetadata.Builder() - .setIntent(bubbleIntent) - .setIcon(info.icon) - .setDesiredHeight(info.height); - } - - public void cancel(int id) { - mNotificationManager.cancel(id); - } - - public void cancelAll() { - mNotificationManager.cancelAll(); - } - - public void cancelLast() { - StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications(); - if (activeNotifications.length > 0) { - mNotificationManager.cancel( - activeNotifications[activeNotifications.length - 1].getId()); - } - } - - public void cancelFirst() { - StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications(); - if (activeNotifications.length > 0) { - mNotificationManager.cancel(activeNotifications[0].getId()); - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java deleted file mode 100644 index a2b580da5898..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.content.ComponentName; - -public class Components { - public static final String PACKAGE_NAME = "com.android.wm.shell.flicker.testapp"; - - public static class SimpleActivity { - public static final String LABEL = "SimpleApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".SimpleActivity"); - } - - public static class FixedActivity { - public static final String EXTRA_FIXED_ORIENTATION = "fixed_orientation"; - public static final String LABEL = "FixedApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".FixedActivity"); - } - - public static class NonResizeableActivity { - public static final String LABEL = "NonResizeableApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".NonResizeableActivity"); - } - - public static class PipActivity { - // Test App > Pip Activity - public static final String LABEL = "PipApp"; - public static final String MENU_ACTION_NO_OP = "No-Op"; - public static final String MENU_ACTION_ON = "On"; - public static final String MENU_ACTION_OFF = "Off"; - public static final String MENU_ACTION_CLEAR = "Clear"; - - // Intent action that this activity dynamically registers to enter picture-in-picture - public static final String ACTION_ENTER_PIP = PACKAGE_NAME + ".PipActivity.ENTER_PIP"; - // Intent action that this activity dynamically registers to set requested orientation. - // Will apply the oriention to the value set in the EXTRA_FIXED_ORIENTATION extra. - public static final String ACTION_SET_REQUESTED_ORIENTATION = - PACKAGE_NAME + ".PipActivity.SET_REQUESTED_ORIENTATION"; - - // Calls enterPictureInPicture() on creation - public static final String EXTRA_ENTER_PIP = "enter_pip"; - // Sets the fixed orientation (can be one of {@link ActivityInfo.ScreenOrientation} - public static final String EXTRA_PIP_ORIENTATION = "fixed_orientation"; - // Adds a click listener to finish this activity when it is clicked - public static final String EXTRA_TAP_TO_FINISH = "tap_to_finish"; - - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".PipActivity"); - } - - public static class ImeActivity { - public static final String LABEL = "ImeApp"; - public static final String ACTION_CLOSE_IME = - PACKAGE_NAME + ".action.CLOSE_IME"; - public static final String ACTION_OPEN_IME = - PACKAGE_NAME + ".action.OPEN_IME"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".ImeActivity"); - } - - public static class SplitScreenActivity { - public static final String LABEL = "SplitScreenPrimaryApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".SplitScreenActivity"); - } - - public static class SplitScreenSecondaryActivity { - public static final String LABEL = "SplitScreenSecondaryApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".SplitScreenSecondaryActivity"); - } - - public static class SendNotificationActivity { - public static final String LABEL = "SendNotificationApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".SendNotificationActivity"); - } - - public static class LaunchBubbleActivity { - public static final String LABEL = "LaunchBubbleApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".LaunchBubbleActivity"); - } - - public static class BubbleActivity { - public static final String LABEL = "BubbleApp"; - public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME, - PACKAGE_NAME + ".BubbleActivity"); - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java deleted file mode 100644 index d4ae6c1313bf..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import static com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION; - -import android.os.Bundle; - -public class FixedActivity extends SimpleActivity { - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - // Set the fixed orientation if requested - if (getIntent().hasExtra(EXTRA_FIXED_ORIENTATION)) { - final int ori = Integer.parseInt(getIntent().getStringExtra(EXTRA_FIXED_ORIENTATION)); - setRequestedOrientation(ori); - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java deleted file mode 100644 index 59c64a1345ab..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; - -public class ImeActivity extends Activity { - private static final String ACTION_OPEN_IME = - "com.android.wm.shell.flicker.testapp.action.OPEN_IME"; - private static final String ACTION_CLOSE_IME = - "com.android.wm.shell.flicker.testapp.action.CLOSE_IME"; - - private InputMethodManager mImm; - private View mEditText; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - WindowManager.LayoutParams p = getWindow().getAttributes(); - p.layoutInDisplayCutoutMode = WindowManager.LayoutParams - .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - getWindow().setAttributes(p); - setContentView(R.layout.activity_ime); - - mEditText = findViewById(R.id.plain_text_input); - mImm = getSystemService(InputMethodManager.class); - - handleIntent(getIntent()); - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - handleIntent(intent); - } - - private void handleIntent(Intent intent) { - final String action = intent.getAction(); - if (ACTION_OPEN_IME.equals(action)) { - mEditText.requestFocus(); - mImm.showSoftInput(mEditText, InputMethodManager.SHOW_FORCED); - } else if (ACTION_CLOSE_IME.equals(action)) { - mImm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0); - mEditText.clearFocus(); - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/LaunchBubbleActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/LaunchBubbleActivity.java deleted file mode 100644 index 71fa66d8a61c..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/LaunchBubbleActivity.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - - -import android.app.Activity; -import android.app.Person; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ShortcutInfo; -import android.content.pm.ShortcutManager; -import android.graphics.drawable.Icon; -import android.os.Bundle; -import android.view.View; - -import java.util.Arrays; - -public class LaunchBubbleActivity extends Activity { - - private BubbleHelper mBubbleHelper; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addInboxShortcut(getApplicationContext()); - mBubbleHelper = BubbleHelper.getInstance(this); - setContentView(R.layout.activity_main); - findViewById(R.id.button_create).setOnClickListener(this::add); - findViewById(R.id.button_cancel).setOnClickListener(this::cancel); - findViewById(R.id.button_cancel_all).setOnClickListener(this::cancelAll); - } - - private void add(View v) { - mBubbleHelper.addNewBubble(false /* autoExpand */, false /* suppressNotif */); - } - - private void cancel(View v) { - mBubbleHelper.cancelLast(); - } - - private void cancelAll(View v) { - mBubbleHelper.cancelAll(); - } - - private void addInboxShortcut(Context context) { - Icon icon = Icon.createWithResource(this, R.drawable.bg); - Person[] persons = new Person[4]; - for (int i = 0; i < persons.length; i++) { - persons[i] = new Person.Builder() - .setBot(false) - .setIcon(icon) - .setName("google" + i) - .setImportant(true) - .build(); - } - - ShortcutInfo shortcut = new ShortcutInfo.Builder(context, "BubbleChat") - .setShortLabel("BubbleChat") - .setLongLived(true) - .setIntent(new Intent(Intent.ACTION_VIEW)) - .setIcon(Icon.createWithResource(context, R.drawable.ic_message)) - .setPersons(persons) - .build(); - ShortcutManager scmanager = context.getSystemService(ShortcutManager.class); - scmanager.addDynamicShortcuts(Arrays.asList(shortcut)); - } - -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java deleted file mode 100644 index 24275e002c7f..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.app.Activity; -import android.os.Bundle; - -public class NonResizeableActivity extends Activity { - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.activity_non_resizeable); - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java deleted file mode 100644 index 615b1730579c..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import static android.media.MediaMetadata.METADATA_KEY_TITLE; -import static android.media.session.PlaybackState.ACTION_PAUSE; -import static android.media.session.PlaybackState.ACTION_PLAY; -import static android.media.session.PlaybackState.ACTION_STOP; -import static android.media.session.PlaybackState.STATE_PAUSED; -import static android.media.session.PlaybackState.STATE_PLAYING; -import static android.media.session.PlaybackState.STATE_STOPPED; - -import static com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP; -import static com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_SET_REQUESTED_ORIENTATION; -import static com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP; -import static com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_PIP_ORIENTATION; - -import android.app.Activity; -import android.app.PendingIntent; -import android.app.PictureInPictureParams; -import android.app.RemoteAction; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.graphics.drawable.Icon; -import android.media.MediaMetadata; -import android.media.session.MediaSession; -import android.media.session.PlaybackState; -import android.os.Bundle; -import android.util.Log; -import android.util.Rational; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.widget.CheckBox; -import android.widget.RadioButton; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class PipActivity extends Activity { - private static final String TAG = PipActivity.class.getSimpleName(); - /** - * A media session title for when the session is in {@link STATE_PLAYING}. - * TvPipNotificationTests check whether the actual notification title matches this string. - */ - private static final String TITLE_STATE_PLAYING = "TestApp media is playing"; - /** - * A media session title for when the session is in {@link STATE_PAUSED}. - * TvPipNotificationTests check whether the actual notification title matches this string. - */ - private static final String TITLE_STATE_PAUSED = "TestApp media is paused"; - - private static final Rational RATIO_DEFAULT = null; - private static final Rational RATIO_SQUARE = new Rational(1, 1); - private static final Rational RATIO_WIDE = new Rational(2, 1); - private static final Rational RATIO_TALL = new Rational(1, 2); - - private static final String PIP_ACTION_NO_OP = "No-Op"; - private static final String PIP_ACTION_OFF = "Off"; - private static final String PIP_ACTION_ON = "On"; - private static final String PIP_ACTION_CLEAR = "Clear"; - private static final String ACTION_NO_OP = "com.android.wm.shell.flicker.testapp.NO_OP"; - private static final String ACTION_SWITCH_OFF = - "com.android.wm.shell.flicker.testapp.SWITCH_OFF"; - private static final String ACTION_SWITCH_ON = "com.android.wm.shell.flicker.testapp.SWITCH_ON"; - private static final String ACTION_CLEAR = "com.android.wm.shell.flicker.testapp.CLEAR"; - - private final PictureInPictureParams.Builder mPipParamsBuilder = - new PictureInPictureParams.Builder() - .setAspectRatio(RATIO_DEFAULT); - private MediaSession mMediaSession; - private final PlaybackState.Builder mPlaybackStateBuilder = new PlaybackState.Builder() - .setActions(ACTION_PLAY | ACTION_PAUSE | ACTION_STOP) - .setState(STATE_STOPPED, 0, 1f); - private PlaybackState mPlaybackState = mPlaybackStateBuilder.build(); - private final MediaMetadata.Builder mMediaMetadataBuilder = new MediaMetadata.Builder(); - - private final List<RemoteAction> mSwitchOffActions = new ArrayList<>(); - private final List<RemoteAction> mSwitchOnActions = new ArrayList<>(); - private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (isInPictureInPictureMode()) { - switch (intent.getAction()) { - case ACTION_SWITCH_ON: - mPipParamsBuilder.setActions(mSwitchOnActions); - break; - case ACTION_SWITCH_OFF: - mPipParamsBuilder.setActions(mSwitchOffActions); - break; - case ACTION_CLEAR: - mPipParamsBuilder.setActions(Collections.emptyList()); - break; - case ACTION_NO_OP: - return; - default: - Log.w(TAG, "Unhandled action=" + intent.getAction()); - return; - } - setPictureInPictureParams(mPipParamsBuilder.build()); - } else { - switch (intent.getAction()) { - case ACTION_ENTER_PIP: - enterPip(null); - break; - case ACTION_SET_REQUESTED_ORIENTATION: - setRequestedOrientation(Integer.parseInt(intent.getStringExtra( - EXTRA_PIP_ORIENTATION))); - break; - default: - Log.w(TAG, "Unhandled action=" + intent.getAction()); - return; - } - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Window window = getWindow(); - final WindowManager.LayoutParams layoutParams = window.getAttributes(); - layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams - .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - window.setAttributes(layoutParams); - - setContentView(R.layout.activity_pip); - - findViewById(R.id.media_session_start) - .setOnClickListener(v -> updateMediaSessionState(STATE_PLAYING)); - findViewById(R.id.media_session_stop) - .setOnClickListener(v -> updateMediaSessionState(STATE_STOPPED)); - - mMediaSession = new MediaSession(this, "WMShell_TestApp"); - mMediaSession.setPlaybackState(mPlaybackStateBuilder.build()); - mMediaSession.setCallback(new MediaSession.Callback() { - @Override - public void onPlay() { - updateMediaSessionState(STATE_PLAYING); - } - - @Override - public void onPause() { - updateMediaSessionState(STATE_PAUSED); - } - - @Override - public void onStop() { - updateMediaSessionState(STATE_STOPPED); - } - }); - - // Build two sets of the custom actions. We'll replace one with the other when 'On'/'Off' - // action is invoked. - // The first set consists of 3 actions: 1) Off; 2) No-Op; 3) Clear. - // The second set consists of 2 actions: 1) On; 2) Clear. - // Upon invocation 'Clear' action clear-off all the custom actions, including itself. - final Icon icon = Icon.createWithResource(this, android.R.drawable.ic_menu_help); - final RemoteAction noOpAction = buildRemoteAction(icon, PIP_ACTION_NO_OP, ACTION_NO_OP); - final RemoteAction switchOnAction = - buildRemoteAction(icon, PIP_ACTION_ON, ACTION_SWITCH_ON); - final RemoteAction switchOffAction = - buildRemoteAction(icon, PIP_ACTION_OFF, ACTION_SWITCH_OFF); - final RemoteAction clearAllAction = buildRemoteAction(icon, PIP_ACTION_CLEAR, ACTION_CLEAR); - mSwitchOffActions.addAll(Arrays.asList(switchOnAction, clearAllAction)); - mSwitchOnActions.addAll(Arrays.asList(noOpAction, switchOffAction, clearAllAction)); - - final IntentFilter filter = new IntentFilter(); - filter.addAction(ACTION_NO_OP); - filter.addAction(ACTION_SWITCH_ON); - filter.addAction(ACTION_SWITCH_OFF); - filter.addAction(ACTION_CLEAR); - filter.addAction(ACTION_SET_REQUESTED_ORIENTATION); - filter.addAction(ACTION_ENTER_PIP); - registerReceiver(mBroadcastReceiver, filter); - - handleIntentExtra(getIntent()); - } - - @Override - protected void onDestroy() { - unregisterReceiver(mBroadcastReceiver); - super.onDestroy(); - } - - @Override - protected void onUserLeaveHint() { - // Only used when auto PiP is disabled. This is to simulate the behavior that an app - // supports regular PiP but not auto PiP. - final boolean manuallyEnterPip = - ((RadioButton) findViewById(R.id.enter_pip_on_leave_manual)).isChecked(); - if (manuallyEnterPip) { - enterPictureInPictureMode(); - } - } - - private RemoteAction buildRemoteAction(Icon icon, String label, String action) { - final Intent intent = new Intent(action); - final PendingIntent pendingIntent = - PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - return new RemoteAction(icon, label, label, pendingIntent); - } - - public void enterPip(View v) { - final boolean withCustomActions = - ((CheckBox) findViewById(R.id.with_custom_actions)).isChecked(); - mPipParamsBuilder.setActions( - withCustomActions ? mSwitchOnActions : Collections.emptyList()); - enterPictureInPictureMode(mPipParamsBuilder.build()); - } - - public void onAutoPipSelected(View v) { - switch (v.getId()) { - case R.id.enter_pip_on_leave_manual: - // disable auto enter PiP - case R.id.enter_pip_on_leave_disabled: - mPipParamsBuilder.setAutoEnterEnabled(false); - setPictureInPictureParams(mPipParamsBuilder.build()); - break; - case R.id.enter_pip_on_leave_autoenter: - mPipParamsBuilder.setAutoEnterEnabled(true); - setPictureInPictureParams(mPipParamsBuilder.build()); - break; - } - } - - public void onRatioSelected(View v) { - switch (v.getId()) { - case R.id.ratio_default: - mPipParamsBuilder.setAspectRatio(RATIO_DEFAULT); - break; - - case R.id.ratio_square: - mPipParamsBuilder.setAspectRatio(RATIO_SQUARE); - break; - - case R.id.ratio_wide: - mPipParamsBuilder.setAspectRatio(RATIO_WIDE); - break; - - case R.id.ratio_tall: - mPipParamsBuilder.setAspectRatio(RATIO_TALL); - break; - } - } - - private void updateMediaSessionState(int newState) { - if (mPlaybackState.getState() == newState) { - return; - } - final String title; - switch (newState) { - case STATE_PLAYING: - title = TITLE_STATE_PLAYING; - break; - case STATE_PAUSED: - title = TITLE_STATE_PAUSED; - break; - case STATE_STOPPED: - title = ""; - break; - - default: - throw new IllegalArgumentException("Unknown state " + newState); - } - - mPlaybackStateBuilder.setState(newState, 0, 1f); - mPlaybackState = mPlaybackStateBuilder.build(); - - mMediaMetadataBuilder.putText(METADATA_KEY_TITLE, title); - - mMediaSession.setPlaybackState(mPlaybackState); - mMediaSession.setMetadata(mMediaMetadataBuilder.build()); - mMediaSession.setActive(newState != STATE_STOPPED); - } - - private void handleIntentExtra(Intent intent) { - // Set the fixed orientation if requested - if (intent.hasExtra(EXTRA_PIP_ORIENTATION)) { - final int ori = Integer.parseInt(getIntent().getStringExtra(EXTRA_PIP_ORIENTATION)); - setRequestedOrientation(ori); - } - // Enter picture in picture with the given aspect ratio if provided - if (intent.hasExtra(EXTRA_ENTER_PIP)) { - mPipParamsBuilder.setActions(mSwitchOnActions); - enterPip(null); - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SendNotificationActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SendNotificationActivity.java deleted file mode 100644 index 8020ef2270a0..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SendNotificationActivity.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.app.Activity; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; - -public class SendNotificationActivity extends Activity { - private NotificationManager mNotificationManager; - private String mChannelId = "Channel id"; - private String mChannelName = "Channel name"; - private NotificationChannel mChannel; - private int mNotifyId = 0; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_notification); - findViewById(R.id.button_send_notification).setOnClickListener(this::sendNotification); - - mChannel = new NotificationChannel(mChannelId, mChannelName, - NotificationManager.IMPORTANCE_DEFAULT); - mNotificationManager = getSystemService(NotificationManager.class); - mNotificationManager.createNotificationChannel(mChannel); - } - - private void sendNotification(View v) { - PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, - new Intent(this, SendNotificationActivity.class), - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); - Notification notification = new Notification.Builder(this, mChannelId) - .setContentTitle("Notification App") - .setContentText("Notification content") - .setWhen(System.currentTimeMillis()) - .setSmallIcon(R.drawable.ic_message) - .setContentIntent(pendingIntent) - .build(); - - mNotificationManager.notify(mNotifyId, notification); - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SimpleActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SimpleActivity.java deleted file mode 100644 index 5343c1893d4e..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SimpleActivity.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.app.Activity; -import android.os.Bundle; -import android.view.WindowManager; - -public class SimpleActivity extends Activity { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - WindowManager.LayoutParams p = getWindow().getAttributes(); - p.layoutInDisplayCutoutMode = WindowManager.LayoutParams - .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - getWindow().setAttributes(p); - setContentView(R.layout.activity_simple); - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SplitScreenActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SplitScreenActivity.java deleted file mode 100644 index 9c82eea1e8b8..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SplitScreenActivity.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.app.Activity; -import android.os.Bundle; - -public class SplitScreenActivity extends Activity { - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.activity_splitscreen); - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SplitScreenSecondaryActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SplitScreenSecondaryActivity.java deleted file mode 100644 index baa1e6fdd1e9..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SplitScreenSecondaryActivity.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.testapp; - -import android.app.Activity; -import android.os.Bundle; - -public class SplitScreenSecondaryActivity extends Activity { - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.activity_splitscreen_secondary); - } -} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestShellExecutor.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestShellExecutor.java index fe8b305093d7..da95c77d2b89 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestShellExecutor.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestShellExecutor.java @@ -48,10 +48,9 @@ public class TestShellExecutor implements ShellExecutor { } public void flushAll() { - final ArrayList<Runnable> tmpRunnable = new ArrayList<>(mRunnables); - mRunnables.clear(); - for (Runnable r : tmpRunnable) { + for (Runnable r : mRunnables) { r.run(); } + mRunnables.clear(); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java index 90a377309edd..5b3b8fd7ad71 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java @@ -54,7 +54,6 @@ import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.window.BackEvent; import android.window.BackNavigationInfo; -import android.window.IBackNaviAnimationController; import android.window.IOnBackInvokedCallback; import androidx.test.filters.SmallTest; @@ -99,9 +98,6 @@ public class BackAnimationControllerTest extends ShellTestCase { @Mock private IOnBackInvokedCallback mIOnBackInvokedCallback; - @Mock - private IBackNaviAnimationController mIBackNaviAnimationController; - private BackAnimationController mController; private int mEventTime = 0; @@ -131,7 +127,7 @@ public class BackAnimationControllerTest extends ShellTestCase { SurfaceControl screenshotSurface, HardwareBuffer hardwareBuffer, int backType, - IOnBackInvokedCallback onBackInvokedCallback, boolean prepareAnimation) { + IOnBackInvokedCallback onBackInvokedCallback) { BackNavigationInfo.Builder builder = new BackNavigationInfo.Builder() .setType(backType) .setDepartingAnimationTarget(topAnimationTarget) @@ -139,8 +135,7 @@ public class BackAnimationControllerTest extends ShellTestCase { .setScreenshotBuffer(hardwareBuffer) .setTaskWindowConfiguration(new WindowConfiguration()) .setOnBackNavigationDone(new RemoteCallback((bundle) -> {})) - .setOnBackInvokedCallback(onBackInvokedCallback) - .setPrepareAnimation(prepareAnimation); + .setOnBackInvokedCallback(onBackInvokedCallback); createNavigationInfo(builder); } @@ -148,7 +143,7 @@ public class BackAnimationControllerTest extends ShellTestCase { private void createNavigationInfo(BackNavigationInfo.Builder builder) { try { doReturn(builder.build()).when(mActivityTaskManager) - .startBackNavigation(anyBoolean(), any(), any()); + .startBackNavigation(anyBoolean(), any()); } catch (RemoteException ex) { ex.rethrowFromSystemServer(); } @@ -180,7 +175,7 @@ public class BackAnimationControllerTest extends ShellTestCase { SurfaceControl screenshotSurface = new SurfaceControl(); HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class); createNavigationInfo(createAnimationTarget(), screenshotSurface, hardwareBuffer, - BackNavigationInfo.TYPE_CROSS_ACTIVITY, null, true); + BackNavigationInfo.TYPE_CROSS_ACTIVITY, null); doMotionEvent(MotionEvent.ACTION_DOWN, 0); verify(mTransaction).setBuffer(screenshotSurface, hardwareBuffer); verify(mTransaction).setVisibility(screenshotSurface, true); @@ -193,7 +188,7 @@ public class BackAnimationControllerTest extends ShellTestCase { HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class); RemoteAnimationTarget animationTarget = createAnimationTarget(); createNavigationInfo(animationTarget, screenshotSurface, hardwareBuffer, - BackNavigationInfo.TYPE_CROSS_ACTIVITY, null, true); + BackNavigationInfo.TYPE_CROSS_ACTIVITY, null); doMotionEvent(MotionEvent.ACTION_DOWN, 0); doMotionEvent(MotionEvent.ACTION_MOVE, 100); // b/207481538, we check that the surface is not moved for now, we can re-enable this once @@ -227,16 +222,15 @@ public class BackAnimationControllerTest extends ShellTestCase { mController.setBackToLauncherCallback(mIOnBackInvokedCallback); RemoteAnimationTarget animationTarget = createAnimationTarget(); createNavigationInfo(animationTarget, null, null, - BackNavigationInfo.TYPE_RETURN_TO_HOME, null, true); + BackNavigationInfo.TYPE_RETURN_TO_HOME, null); doMotionEvent(MotionEvent.ACTION_DOWN, 0); // Check that back start and progress is dispatched when first move. doMotionEvent(MotionEvent.ACTION_MOVE, 100); - simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget); verify(mIOnBackInvokedCallback).onBackStarted(); ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class); - verify(mIOnBackInvokedCallback, atLeastOnce()).onBackProgressed(backEventCaptor.capture()); + verify(mIOnBackInvokedCallback).onBackProgressed(backEventCaptor.capture()); assertEquals(animationTarget, backEventCaptor.getValue().getDepartingAnimationTarget()); // Check that back invocation is dispatched. @@ -261,7 +255,7 @@ public class BackAnimationControllerTest extends ShellTestCase { IOnBackInvokedCallback appCallback = mock(IOnBackInvokedCallback.class); ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class); createNavigationInfo(animationTarget, null, null, - BackNavigationInfo.TYPE_RETURN_TO_HOME, appCallback, false); + BackNavigationInfo.TYPE_RETURN_TO_HOME, appCallback); triggerBackGesture(); @@ -279,10 +273,9 @@ public class BackAnimationControllerTest extends ShellTestCase { mController.setBackToLauncherCallback(mIOnBackInvokedCallback); RemoteAnimationTarget animationTarget = createAnimationTarget(); createNavigationInfo(animationTarget, null, null, - BackNavigationInfo.TYPE_RETURN_TO_HOME, null, true); + BackNavigationInfo.TYPE_RETURN_TO_HOME, null); triggerBackGesture(); - simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget); // Check that back invocation is dispatched. verify(mIOnBackInvokedCallback).onBackInvoked(); @@ -301,7 +294,6 @@ public class BackAnimationControllerTest extends ShellTestCase { // Verify that we start accepting gestures again once transition finishes. doMotionEvent(MotionEvent.ACTION_DOWN, 0); doMotionEvent(MotionEvent.ACTION_MOVE, 100); - simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget); verify(mIOnBackInvokedCallback).onBackStarted(); } @@ -310,17 +302,15 @@ public class BackAnimationControllerTest extends ShellTestCase { mController.setBackToLauncherCallback(mIOnBackInvokedCallback); RemoteAnimationTarget animationTarget = createAnimationTarget(); createNavigationInfo(animationTarget, null, null, - BackNavigationInfo.TYPE_RETURN_TO_HOME, null, true); + BackNavigationInfo.TYPE_RETURN_TO_HOME, null); triggerBackGesture(); - simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget); reset(mIOnBackInvokedCallback); // Simulate transition timeout. mShellExecutor.flushAll(); doMotionEvent(MotionEvent.ACTION_DOWN, 0); doMotionEvent(MotionEvent.ACTION_MOVE, 100); - simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget); verify(mIOnBackInvokedCallback).onBackStarted(); } @@ -331,12 +321,11 @@ public class BackAnimationControllerTest extends ShellTestCase { RemoteAnimationTarget animationTarget = createAnimationTarget(); createNavigationInfo(animationTarget, null, null, - BackNavigationInfo.TYPE_RETURN_TO_HOME, null, true); + BackNavigationInfo.TYPE_RETURN_TO_HOME, null); doMotionEvent(MotionEvent.ACTION_DOWN, 0); // Check that back start and progress is dispatched when first move. doMotionEvent(MotionEvent.ACTION_MOVE, 100); - simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME, animationTarget); verify(mIOnBackInvokedCallback).onBackStarted(); // Check that back invocation is dispatched. @@ -360,14 +349,4 @@ public class BackAnimationControllerTest extends ShellTestCase { BackEvent.EDGE_LEFT); mEventTime += 10; } - - private void simulateRemoteAnimationStart(int type, RemoteAnimationTarget animationTarget) - throws RemoteException { - if (mController.mIBackAnimationRunner != null) { - final RemoteAnimationTarget[] targets = new RemoteAnimationTarget[]{animationTarget}; - mController.mIBackAnimationRunner.onAnimationStart(mIBackNaviAnimationController, type, - targets, null, null); - mShellExecutor.flushAll(); - } - } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt index 05e472245b4a..cc51efd7e16b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt @@ -179,6 +179,16 @@ class TvPipBoundsControllerTest { } @Test + fun testImmediatePlacement_DoNotStashIfAlreadyUnstashed() { + triggerImmediatePlacement(STASHED_PLACEMENT_RESTASH) + assertMovement(STASHED_BOUNDS) + assertMovementAt(time + STASH_DURATION, ANCHOR_BOUNDS) + + triggerImmediatePlacement(STASHED_PLACEMENT) + assertNoMovementUpTo(time + FAR_FUTURE) + } + + @Test fun testInMoveMode_KeepAtAnchor() { startMoveMode() triggerImmediatePlacement(STASHED_MOVED_PLACEMENT_RESTASH) diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp index c80fb188e70f..eb8d26adc7d7 100644 --- a/libs/androidfw/Android.bp +++ b/libs/androidfw/Android.bp @@ -33,6 +33,7 @@ license { cc_defaults { name: "libandroidfw_defaults", + cpp_std: "gnu++2b", cflags: [ "-Werror", "-Wunreachable-code", @@ -60,6 +61,7 @@ cc_library { "AssetManager2.cpp", "AssetsProvider.cpp", "AttributeResolution.cpp", + "BigBuffer.cpp", "ChunkIterator.cpp", "ConfigDescription.cpp", "Idmap.cpp", @@ -69,9 +71,11 @@ cc_library { "misc.cpp", "ObbFile.cpp", "PosixUtils.cpp", + "ResourceTimer.cpp", "ResourceTypes.cpp", "ResourceUtils.cpp", "StreamingZipInflater.cpp", + "StringPool.cpp", "TypeWrappers.cpp", "Util.cpp", "ZipFileRO.cpp", @@ -161,6 +165,7 @@ cc_test { "tests/AssetManager2_test.cpp", "tests/AttributeFinder_test.cpp", "tests/AttributeResolution_test.cpp", + "tests/BigBuffer_test.cpp", "tests/ByteBucketArray_test.cpp", "tests/Config_test.cpp", "tests/ConfigDescription_test.cpp", @@ -169,10 +174,12 @@ cc_test { "tests/Idmap_test.cpp", "tests/LoadedArsc_test.cpp", "tests/Locale_test.cpp", + "tests/ResourceTimer_test.cpp", "tests/ResourceUtils_test.cpp", "tests/ResTable_test.cpp", "tests/Split_test.cpp", "tests/StringPiece_test.cpp", + "tests/StringPool_test.cpp", "tests/Theme_test.cpp", "tests/TypeWrappers_test.cpp", "tests/ZipUtils_test.cpp", diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 2beb33abe782..9aa37872b8de 100755 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -141,6 +141,9 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_ return {}; } loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags); + } else if (loaded_idmap != nullptr && + IsFabricatedOverlay(std::string(loaded_idmap->OverlayApkPath()))) { + loaded_arsc = LoadedArsc::Load(loaded_idmap.get()); } else { loaded_arsc = LoadedArsc::CreateEmpty(); } diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 136fc6ca4e2a..235700b27c25 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -611,7 +611,21 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( } if (overlay_entry.IsInlineValue()) { // The target resource is overlaid by an inline value not represented by a resource. - result->entry = overlay_entry.GetInlineValue(); + 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 (!frro_found) { + continue; + } + result->entry = best_frro_value; result->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable(); result->cookie = id_map.cookie; diff --git a/libs/androidfw/BigBuffer.cpp b/libs/androidfw/BigBuffer.cpp new file mode 100644 index 000000000000..bedfc49a1b0d --- /dev/null +++ b/libs/androidfw/BigBuffer.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <androidfw/BigBuffer.h> + +#include <algorithm> +#include <memory> +#include <vector> + +#include "android-base/logging.h" + +namespace android { + +void* BigBuffer::NextBlockImpl(size_t size) { + if (!blocks_.empty()) { + Block& block = blocks_.back(); + if (block.block_size_ - block.size >= size) { + void* out_buffer = block.buffer.get() + block.size; + block.size += size; + size_ += size; + return out_buffer; + } + } + + const size_t actual_size = std::max(block_size_, size); + + Block block = {}; + + // Zero-allocate the block's buffer. + block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actual_size]()); + CHECK(block.buffer); + + block.size = size; + block.block_size_ = actual_size; + + blocks_.push_back(std::move(block)); + size_ += size; + return blocks_.back().buffer.get(); +} + +void* BigBuffer::NextBlock(size_t* out_size) { + if (!blocks_.empty()) { + Block& block = blocks_.back(); + if (block.size != block.block_size_) { + void* out_buffer = block.buffer.get() + block.size; + size_t size = block.block_size_ - block.size; + block.size = block.block_size_; + size_ += size; + *out_size = size; + return out_buffer; + } + } + + // Zero-allocate the block's buffer. + Block block = {}; + block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[block_size_]()); + CHECK(block.buffer); + block.size = block_size_; + block.block_size_ = block_size_; + blocks_.push_back(std::move(block)); + size_ += block_size_; + *out_size = block_size_; + return blocks_.back().buffer.get(); +} + +std::string BigBuffer::to_string() const { + std::string result; + for (const Block& block : blocks_) { + result.append(block.buffer.get(), block.buffer.get() + block.size); + } + return result; +} + +} // namespace android diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index efd1f6a25786..e122d4844ee9 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -56,6 +56,8 @@ struct Idmap_header { struct Idmap_data_header { uint32_t target_entry_count; uint32_t target_inline_entry_count; + uint32_t target_inline_entry_value_count; + uint32_t configuration_count; uint32_t overlay_entry_count; uint32_t string_pool_index_offset; @@ -68,6 +70,12 @@ struct Idmap_target_entry { struct Idmap_target_entry_inline { uint32_t target_id; + uint32_t start_value_index; + uint32_t value_count; +}; + +struct Idmap_target_entry_inline_value { + uint32_t config_index; Res_value value; }; @@ -138,11 +146,15 @@ status_t OverlayDynamicRefTable::lookupResourceIdNoRewrite(uint32_t* resId) cons IdmapResMap::IdmapResMap(const Idmap_data_header* data_header, const Idmap_target_entry* entries, const Idmap_target_entry_inline* inline_entries, + const Idmap_target_entry_inline_value* inline_entry_values, + const ConfigDescription* configs, uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table) : data_header_(data_header), entries_(entries), inline_entries_(inline_entries), + inline_entry_values_(inline_entry_values), + configurations_(configs), target_assigned_package_id_(target_assigned_package_id), overlay_ref_table_(overlay_ref_table) { } @@ -183,7 +195,13 @@ IdmapResMap::Result IdmapResMap::Lookup(uint32_t target_res_id) const { if (inline_entry != end_inline_entry && (0x00FFFFFFU & dtohl(inline_entry->target_id)) == target_res_id) { - return Result(inline_entry->value); + std::map<ConfigDescription, Res_value> values_map; + for (int i = 0; i < inline_entry->value_count; i++) { + const auto& value = inline_entry_values_[inline_entry->start_value_index + i]; + const auto& config = configurations_[value.config_index]; + values_map[config] = value.value; + } + return Result(values_map); } return {}; } @@ -237,6 +255,8 @@ LoadedIdmap::LoadedIdmap(std::string&& idmap_path, const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, const Idmap_target_entry_inline* target_inline_entries, + const Idmap_target_entry_inline_value* inline_entry_values, + const ConfigDescription* configs, const Idmap_overlay_entry* overlay_entries, std::unique_ptr<ResStringPool>&& string_pool, std::string_view overlay_apk_path, @@ -245,6 +265,8 @@ LoadedIdmap::LoadedIdmap(std::string&& idmap_path, data_header_(data_header), target_entries_(target_entries), target_inline_entries_(target_inline_entries), + inline_entry_values_(inline_entry_values), + configurations_(configs), overlay_entries_(overlay_entries), string_pool_(std::move(string_pool)), idmap_path_(std::move(idmap_path)), @@ -303,6 +325,21 @@ std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_path, if (target_inline_entries == nullptr) { return {}; } + + auto target_inline_entry_values = ReadType<Idmap_target_entry_inline_value>( + &data_ptr, &data_size, "target inline values", + dtohl(data_header->target_inline_entry_value_count)); + if (target_inline_entry_values == nullptr) { + return {}; + } + + auto configurations = ReadType<ConfigDescription>( + &data_ptr, &data_size, "configurations", + dtohl(data_header->configuration_count)); + if (configurations == nullptr) { + return {}; + } + auto overlay_entries = ReadType<Idmap_overlay_entry>(&data_ptr, &data_size, "target inline", dtohl(data_header->overlay_entry_count)); if (overlay_entries == nullptr) { @@ -329,8 +366,8 @@ std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_path, // Can't use make_unique because LoadedIdmap constructor is private. return std::unique_ptr<LoadedIdmap>( new LoadedIdmap(idmap_path.to_string(), header, data_header, target_entries, - target_inline_entries, overlay_entries, std::move(idmap_string_pool), - *target_path, *overlay_path)); + target_inline_entries, target_inline_entry_values, configurations, + overlay_entries, std::move(idmap_string_pool), *target_path, *overlay_path)); } bool LoadedIdmap::IsUpToDate() const { diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index 35b6170fae5b..5b69cca2d747 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -820,6 +820,13 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, return true; } +bool LoadedArsc::LoadStringPool(const LoadedIdmap* loaded_idmap) { + if (loaded_idmap != nullptr) { + global_string_pool_ = util::make_unique<OverlayStringPool>(loaded_idmap); + } + return true; +} + std::unique_ptr<LoadedArsc> LoadedArsc::Load(incfs::map_ptr<void> data, const size_t length, const LoadedIdmap* loaded_idmap, @@ -855,6 +862,16 @@ std::unique_ptr<LoadedArsc> LoadedArsc::Load(incfs::map_ptr<void> data, return loaded_arsc; } +std::unique_ptr<LoadedArsc> LoadedArsc::Load(const LoadedIdmap* loaded_idmap) { + ATRACE_NAME("LoadedArsc::Load"); + + // Not using make_unique because the constructor is private. + std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc()); + loaded_arsc->LoadStringPool(loaded_idmap); + return loaded_arsc; +} + + std::unique_ptr<LoadedArsc> LoadedArsc::CreateEmpty() { return std::unique_ptr<LoadedArsc>(new LoadedArsc()); } diff --git a/libs/androidfw/ResourceTimer.cpp b/libs/androidfw/ResourceTimer.cpp new file mode 100644 index 000000000000..44128d9e4e3d --- /dev/null +++ b/libs/androidfw/ResourceTimer.cpp @@ -0,0 +1,271 @@ +/* + * 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 <unistd.h> +#include <string.h> + +#include <map> +#include <atomic> + +#include <utils/Log.h> +#include <androidfw/ResourceTimer.h> + +// The following block allows compilation on windows, which does not have getuid(). +#ifdef _WIN32 +#ifdef ERROR +#undef ERROR +#endif +#define getuid() (getUidWindows_) +#endif + +namespace android { + +namespace { + +#ifdef _WIN32 +// A temporary to confuse lint into thinking that getuid() on windows might return something other +// than zero. +int getUidWindows_ = 0; +#endif + +// The number of nanoseconds in a microsecond. +static const unsigned int US = 1000; +// The number of nanoseconds in a second. +static const unsigned int S = 1000 * 1000 * 1000; + +// Return the difference between two timespec values. The difference is in nanoseconds. If the +// return value would exceed 2s (2^31 nanoseconds) then UINT_MAX is returned. +unsigned int diffInNs(timespec const &a, timespec const &b) { + timespec r = { 0, 0 }; + r.tv_nsec = a.tv_nsec - b.tv_nsec; + if (r.tv_nsec < 0) { + r.tv_sec = -1; + r.tv_nsec += S; + } + r.tv_sec = r.tv_sec + (a.tv_sec - b.tv_sec); + if (r.tv_sec > 2) return UINT_MAX; + unsigned int result = (r.tv_sec * S) + r.tv_nsec; + if (result > 2 * S) return UINT_MAX; + return result; +} + +} + +ResourceTimer::ResourceTimer(Counter api) + : active_(enabled_.load()), + api_(api) { + if (active_) { + clock_gettime(CLOCK_MONOTONIC, &start_); + } +} + +ResourceTimer::~ResourceTimer() { + record(); +} + +void ResourceTimer::enable() { + if (!enabled_.load()) counter_ = new GuardedTimer[ResourceTimer::counterSize]; + enabled_.store(true); +} + +void ResourceTimer::cancel() { + active_ = false; +} + +void ResourceTimer::record() { + if (!active_) return; + + struct timespec end; + clock_gettime(CLOCK_MONOTONIC, &end); + // Get the difference in microseconds. + const unsigned int ticks = diffInNs(end, start_); + ScopedTimer t(counter_[toIndex(api_)]); + t->record(ticks); + active_ = false; +} + +bool ResourceTimer::copy(int counter, Timer &dst, bool reset) { + ScopedTimer t(counter_[counter]); + if (t->count == 0) { + dst.reset(); + if (reset) t->reset(); + return false; + } + Timer::copy(dst, *t, reset); + return true; +} + +void ResourceTimer::reset() { + for (int i = 0; i < counterSize; i++) { + ScopedTimer t(counter_[i]); + t->reset(); + } +} + +ResourceTimer::Timer::Timer() { + // Ensure newly-created objects are zeroed. + memset(buckets, 0, sizeof(buckets)); + reset(); +} + +ResourceTimer::Timer::~Timer() { + for (int d = 0; d < MaxDimension; d++) { + delete[] buckets[d]; + } +} + +void ResourceTimer::Timer::freeBuckets() { + for (int d = 0; d < MaxDimension; d++) { + delete[] buckets[d]; + buckets[d] = 0; + } +} + +void ResourceTimer::Timer::reset() { + count = total = mintime = maxtime = 0; + memset(largest, 0, sizeof(largest)); + memset(&pvalues, 0, sizeof(pvalues)); + // Zero the histogram, keeping any allocated dimensions. + for (int d = 0; d < MaxDimension; d++) { + if (buckets[d] != 0) memset(buckets[d], 0, sizeof(int) * MaxBuckets); + } +} + +void ResourceTimer::Timer::copy(Timer &dst, Timer &src, bool reset) { + dst.freeBuckets(); + dst = src; + // Clean up the histograms. + if (reset) { + // Do NOT free the src buckets because they being used by dst. + memset(src.buckets, 0, sizeof(src.buckets)); + src.reset(); + } else { + for (int d = 0; d < MaxDimension; d++) { + if (src.buckets[d] != nullptr) { + dst.buckets[d] = new int[MaxBuckets]; + memcpy(dst.buckets[d], src.buckets[d], sizeof(int) * MaxBuckets); + } + } + } +} + +void ResourceTimer::Timer::record(int ticks) { + // Record that the event happened. + count++; + + total += ticks; + if (mintime == 0 || ticks < mintime) mintime = ticks; + if (ticks > maxtime) maxtime = ticks; + + // Do not add oversized events to the histogram. + if (ticks != UINT_MAX) { + for (int d = 0; d < MaxDimension; d++) { + if (ticks < range[d]) { + if (buckets[d] == 0) { + buckets[d] = new int[MaxBuckets]; + memset(buckets[d], 0, sizeof(int) * MaxBuckets); + } + if (ticks < width[d]) { + // Special case: never write to bucket 0 because it complicates the percentile logic. + // However, this is always the smallest possible value to it is very unlikely to ever + // affect any of the percentile results. + buckets[d][1]++; + } else { + buckets[d][ticks / width[d]]++; + } + break; + } + } + } + + // The list of largest times is sorted with the biggest value at index 0 and the smallest at + // index MaxLargest-1. The incoming tick count should be added to the array only if it is + // larger than the current value at MaxLargest-1. + if (ticks > largest[Timer::MaxLargest-1]) { + for (size_t i = 0; i < Timer::MaxLargest; i++) { + if (ticks > largest[i]) { + if (i < Timer::MaxLargest-1) { + for (size_t j = Timer::MaxLargest - 1; j > i; j--) { + largest[j] = largest[j-1]; + } + } + largest[i] = ticks; + break; + } + } + } +} + +void ResourceTimer::Timer::Percentile::compute( + int cumulative, int current, int count, int width, int time) { + nominal = time; + nominal_actual = (cumulative * 100) / count; + floor = nominal - width; + floor_actual = ((cumulative - current) * 100) / count; +} + +void ResourceTimer::Timer::compute() { + memset(&pvalues, 0, sizeof(pvalues)); + + float l50 = count / 2.0; + float l90 = (count * 9.0) / 10.0; + float l95 = (count * 95.0) / 100.0; + float l99 = (count * 99.0) / 100.0; + + int sum = 0; + for (int d = 0; d < MaxDimension; d++) { + if (buckets[d] == 0) continue; + for (int j = 0; j < MaxBuckets && sum < count; j++) { + // Empty buckets don't contribute to the answers. Skip them. + if (buckets[d][j] == 0) continue; + sum += buckets[d][j]; + // A word on indexing. j is never zero in the following lines. buckets[0][0] corresponds + // to a delay of 0us, which cannot happen. buckets[n][0], for n > 0 overlaps a value in + // buckets[n-1], and the code would have stopped there. + if (sum >= l50 && pvalues.p50.nominal == 0) { + pvalues.p50.compute(sum, buckets[d][j], count, width[d], j * width[d]); + } + if (sum >= l90 && pvalues.p90.nominal == 0) { + pvalues.p90.compute(sum, buckets[d][j], count, width[d], j * width[d]); + } + if (sum >= l95 && pvalues.p95.nominal == 0) { + pvalues.p95.compute(sum, buckets[d][j], count, width[d], j * width[d]); + } + if (sum >= l99 && pvalues.p99.nominal == 0) { + pvalues.p99.compute(sum, buckets[d][j], count, width[d], j * width[d]); + } + } + } +} + +char const *ResourceTimer::toString(ResourceTimer::Counter counter) { + switch (counter) { + case Counter::GetResourceValue: + return "GetResourceValue"; + case Counter::RetrieveAttributes: + return "RetrieveAttributes"; + }; + return "Unknown"; +} + +std::atomic<bool> ResourceTimer::enabled_(false); +std::atomic<ResourceTimer::GuardedTimer *> ResourceTimer::counter_(nullptr); + +const int ResourceTimer::Timer::range[] = { 100 * US, 1000 * US, 10*1000 * US, 100*1000 * US }; +const int ResourceTimer::Timer::width[] = { 1 * US, 10 * US, 100 * US, 1000 * US }; + + +} // namespace android diff --git a/libs/androidfw/StringPool.cpp b/libs/androidfw/StringPool.cpp new file mode 100644 index 000000000000..b59e906f6281 --- /dev/null +++ b/libs/androidfw/StringPool.cpp @@ -0,0 +1,508 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <androidfw/BigBuffer.h> +#include <androidfw/StringPool.h> + +#include <algorithm> +#include <memory> +#include <string> + +#include "android-base/logging.h" +#include "androidfw/ResourceTypes.h" +#include "androidfw/StringPiece.h" +#include "androidfw/Util.h" + +using ::android::StringPiece; + +namespace android { + +StringPool::Ref::Ref() : entry_(nullptr) { +} + +StringPool::Ref::Ref(const StringPool::Ref& rhs) : entry_(rhs.entry_) { + if (entry_ != nullptr) { + entry_->ref_++; + } +} + +StringPool::Ref::Ref(StringPool::Entry* entry) : entry_(entry) { + if (entry_ != nullptr) { + entry_->ref_++; + } +} + +StringPool::Ref::~Ref() { + if (entry_ != nullptr) { + entry_->ref_--; + } +} + +StringPool::Ref& StringPool::Ref::operator=(const StringPool::Ref& rhs) { + if (rhs.entry_ != nullptr) { + rhs.entry_->ref_++; + } + + if (entry_ != nullptr) { + entry_->ref_--; + } + entry_ = rhs.entry_; + return *this; +} + +bool StringPool::Ref::operator==(const Ref& rhs) const { + return entry_->value == rhs.entry_->value; +} + +bool StringPool::Ref::operator!=(const Ref& rhs) const { + return entry_->value != rhs.entry_->value; +} + +const std::string* StringPool::Ref::operator->() const { + return &entry_->value; +} + +const std::string& StringPool::Ref::operator*() const { + return entry_->value; +} + +size_t StringPool::Ref::index() const { + // Account for the styles, which *always* come first. + return entry_->pool_->styles_.size() + entry_->index_; +} + +const StringPool::Context& StringPool::Ref::GetContext() const { + return entry_->context; +} + +StringPool::StyleRef::StyleRef() : entry_(nullptr) { +} + +StringPool::StyleRef::StyleRef(const StringPool::StyleRef& rhs) : entry_(rhs.entry_) { + if (entry_ != nullptr) { + entry_->ref_++; + } +} + +StringPool::StyleRef::StyleRef(StringPool::StyleEntry* entry) : entry_(entry) { + if (entry_ != nullptr) { + entry_->ref_++; + } +} + +StringPool::StyleRef::~StyleRef() { + if (entry_ != nullptr) { + entry_->ref_--; + } +} + +StringPool::StyleRef& StringPool::StyleRef::operator=(const StringPool::StyleRef& rhs) { + if (rhs.entry_ != nullptr) { + rhs.entry_->ref_++; + } + + if (entry_ != nullptr) { + entry_->ref_--; + } + entry_ = rhs.entry_; + return *this; +} + +bool StringPool::StyleRef::operator==(const StyleRef& rhs) const { + if (entry_->value != rhs.entry_->value) { + return false; + } + + if (entry_->spans.size() != rhs.entry_->spans.size()) { + return false; + } + + auto rhs_iter = rhs.entry_->spans.begin(); + for (const Span& span : entry_->spans) { + const Span& rhs_span = *rhs_iter; + if (span.first_char != rhs_span.first_char || span.last_char != rhs_span.last_char || + span.name != rhs_span.name) { + return false; + } + } + return true; +} + +bool StringPool::StyleRef::operator!=(const StyleRef& rhs) const { + return !operator==(rhs); +} + +const StringPool::StyleEntry* StringPool::StyleRef::operator->() const { + return entry_; +} + +const StringPool::StyleEntry& StringPool::StyleRef::operator*() const { + return *entry_; +} + +size_t StringPool::StyleRef::index() const { + return entry_->index_; +} + +const StringPool::Context& StringPool::StyleRef::GetContext() const { + return entry_->context; +} + +StringPool::Ref StringPool::MakeRef(const StringPiece& str) { + return MakeRefImpl(str, Context{}, true); +} + +StringPool::Ref StringPool::MakeRef(const StringPiece& str, const Context& context) { + return MakeRefImpl(str, context, true); +} + +StringPool::Ref StringPool::MakeRefImpl(const StringPiece& str, const Context& context, + bool unique) { + if (unique) { + auto range = indexed_strings_.equal_range(str); + for (auto iter = range.first; iter != range.second; ++iter) { + if (context.priority == iter->second->context.priority) { + return Ref(iter->second); + } + } + } + + std::unique_ptr<Entry> entry(new Entry()); + entry->value = str.to_string(); + entry->context = context; + entry->index_ = strings_.size(); + entry->ref_ = 0; + entry->pool_ = this; + + Entry* borrow = entry.get(); + strings_.emplace_back(std::move(entry)); + indexed_strings_.insert(std::make_pair(StringPiece(borrow->value), borrow)); + return Ref(borrow); +} + +StringPool::Ref StringPool::MakeRef(const Ref& ref) { + if (ref.entry_->pool_ == this) { + return ref; + } + return MakeRef(ref.entry_->value, ref.entry_->context); +} + +StringPool::StyleRef StringPool::MakeRef(const StyleString& str) { + return MakeRef(str, Context{}); +} + +StringPool::StyleRef StringPool::MakeRef(const StyleString& str, const Context& context) { + std::unique_ptr<StyleEntry> entry(new StyleEntry()); + entry->value = str.str; + entry->context = context; + entry->index_ = styles_.size(); + entry->ref_ = 0; + for (const android::Span& span : str.spans) { + entry->spans.emplace_back(Span{MakeRef(span.name), span.first_char, span.last_char}); + } + + StyleEntry* borrow = entry.get(); + styles_.emplace_back(std::move(entry)); + return StyleRef(borrow); +} + +StringPool::StyleRef StringPool::MakeRef(const StyleRef& ref) { + std::unique_ptr<StyleEntry> entry(new StyleEntry()); + entry->value = ref.entry_->value; + entry->context = ref.entry_->context; + entry->index_ = styles_.size(); + entry->ref_ = 0; + for (const Span& span : ref.entry_->spans) { + entry->spans.emplace_back(Span{MakeRef(*span.name), span.first_char, span.last_char}); + } + + StyleEntry* borrow = entry.get(); + styles_.emplace_back(std::move(entry)); + return StyleRef(borrow); +} + +void StringPool::ReAssignIndices() { + // Assign the style indices. + const size_t style_len = styles_.size(); + for (size_t index = 0; index < style_len; index++) { + styles_[index]->index_ = index; + } + + // Assign the string indices. + const size_t string_len = strings_.size(); + for (size_t index = 0; index < string_len; index++) { + strings_[index]->index_ = index; + } +} + +void StringPool::Merge(StringPool&& pool) { + // First, change the owning pool for the incoming strings. + for (std::unique_ptr<Entry>& entry : pool.strings_) { + entry->pool_ = this; + } + + // Now move the styles, strings, and indices over. + std::move(pool.styles_.begin(), pool.styles_.end(), std::back_inserter(styles_)); + pool.styles_.clear(); + std::move(pool.strings_.begin(), pool.strings_.end(), std::back_inserter(strings_)); + pool.strings_.clear(); + indexed_strings_.insert(pool.indexed_strings_.begin(), pool.indexed_strings_.end()); + pool.indexed_strings_.clear(); + + ReAssignIndices(); +} + +void StringPool::HintWillAdd(size_t string_count, size_t style_count) { + strings_.reserve(strings_.size() + string_count); + styles_.reserve(styles_.size() + style_count); +} + +void StringPool::Prune() { + const auto iter_end = indexed_strings_.end(); + auto index_iter = indexed_strings_.begin(); + while (index_iter != iter_end) { + if (index_iter->second->ref_ <= 0) { + index_iter = indexed_strings_.erase(index_iter); + } else { + ++index_iter; + } + } + + auto end_iter2 = + std::remove_if(strings_.begin(), strings_.end(), + [](const std::unique_ptr<Entry>& entry) -> bool { return entry->ref_ <= 0; }); + auto end_iter3 = std::remove_if( + styles_.begin(), styles_.end(), + [](const std::unique_ptr<StyleEntry>& entry) -> bool { return entry->ref_ <= 0; }); + + // Remove the entries at the end or else we'll be accessing a deleted string from the StyleEntry. + strings_.erase(end_iter2, strings_.end()); + styles_.erase(end_iter3, styles_.end()); + + ReAssignIndices(); +} + +template <typename E> +static void SortEntries( + std::vector<std::unique_ptr<E>>& entries, + const std::function<int(const StringPool::Context&, const StringPool::Context&)>& cmp) { + using UEntry = std::unique_ptr<E>; + + if (cmp != nullptr) { + std::sort(entries.begin(), entries.end(), [&cmp](const UEntry& a, const UEntry& b) -> bool { + int r = cmp(a->context, b->context); + if (r == 0) { + r = a->value.compare(b->value); + } + return r < 0; + }); + } else { + std::sort(entries.begin(), entries.end(), + [](const UEntry& a, const UEntry& b) -> bool { return a->value < b->value; }); + } +} + +void StringPool::Sort(const std::function<int(const Context&, const Context&)>& cmp) { + SortEntries(styles_, cmp); + SortEntries(strings_, cmp); + ReAssignIndices(); +} + +template <typename T> +static T* EncodeLength(T* data, size_t length) { + static_assert(std::is_integral<T>::value, "wat."); + + constexpr size_t kMask = 1 << ((sizeof(T) * 8) - 1); + constexpr size_t kMaxSize = kMask - 1; + if (length > kMaxSize) { + *data++ = kMask | (kMaxSize & (length >> (sizeof(T) * 8))); + } + *data++ = length; + return data; +} + +/** + * Returns the maximum possible string length that can be successfully encoded + * using 2 units of the specified T. + * EncodeLengthMax<char> -> maximum unit length of 0x7FFF + * EncodeLengthMax<char16_t> -> maximum unit length of 0x7FFFFFFF + **/ +template <typename T> +static size_t EncodeLengthMax() { + static_assert(std::is_integral<T>::value, "wat."); + + constexpr size_t kMask = 1 << ((sizeof(T) * 8 * 2) - 1); + constexpr size_t max = kMask - 1; + return max; +} + +/** + * Returns the number of units (1 or 2) needed to encode the string length + * before writing the string. + */ +template <typename T> +static size_t EncodedLengthUnits(size_t length) { + static_assert(std::is_integral<T>::value, "wat."); + + constexpr size_t kMask = 1 << ((sizeof(T) * 8) - 1); + constexpr size_t kMaxSize = kMask - 1; + return length > kMaxSize ? 2 : 1; +} + +const std::string kStringTooLarge = "STRING_TOO_LARGE"; + +static bool EncodeString(const std::string& str, const bool utf8, BigBuffer* out, + IDiagnostics* diag) { + if (utf8) { + const std::string& encoded = util::Utf8ToModifiedUtf8(str); + const ssize_t utf16_length = + utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(encoded.data()), encoded.size()); + CHECK(utf16_length >= 0); + + // Make sure the lengths to be encoded do not exceed the maximum length that + // can be encoded using chars + if ((((size_t)encoded.size()) > EncodeLengthMax<char>()) || + (((size_t)utf16_length) > EncodeLengthMax<char>())) { + diag->Error(DiagMessage() << "string too large to encode using UTF-8 " + << "written instead as '" << kStringTooLarge << "'"); + + EncodeString(kStringTooLarge, utf8, out, diag); + return false; + } + + const size_t total_size = EncodedLengthUnits<char>(utf16_length) + + EncodedLengthUnits<char>(encoded.size()) + encoded.size() + 1; + + char* data = out->NextBlock<char>(total_size); + + // First encode the UTF16 string length. + data = EncodeLength(data, utf16_length); + + // Now encode the size of the real UTF8 string. + data = EncodeLength(data, encoded.size()); + strncpy(data, encoded.data(), encoded.size()); + + } else { + const std::u16string encoded = util::Utf8ToUtf16(str); + const ssize_t utf16_length = encoded.size(); + + // Make sure the length to be encoded does not exceed the maximum possible + // length that can be encoded + if (((size_t)utf16_length) > EncodeLengthMax<char16_t>()) { + diag->Error(DiagMessage() << "string too large to encode using UTF-16 " + << "written instead as '" << kStringTooLarge << "'"); + + EncodeString(kStringTooLarge, utf8, out, diag); + return false; + } + + // Total number of 16-bit words to write. + const size_t total_size = EncodedLengthUnits<char16_t>(utf16_length) + encoded.size() + 1; + + char16_t* data = out->NextBlock<char16_t>(total_size); + + // Encode the actual UTF16 string length. + data = EncodeLength(data, utf16_length); + const size_t byte_length = encoded.size() * sizeof(char16_t); + + // NOTE: For some reason, strncpy16(data, entry->value.data(), + // entry->value.size()) truncates the string. + memcpy(data, encoded.data(), byte_length); + + // The null-terminating character is already here due to the block of data + // being set to 0s on allocation. + } + + return true; +} + +bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8, IDiagnostics* diag) { + bool no_error = true; + const size_t start_index = out->size(); + android::ResStringPool_header* header = out->NextBlock<android::ResStringPool_header>(); + header->header.type = util::HostToDevice16(android::RES_STRING_POOL_TYPE); + header->header.headerSize = util::HostToDevice16(sizeof(*header)); + header->stringCount = util::HostToDevice32(pool.size()); + header->styleCount = util::HostToDevice32(pool.styles_.size()); + if (utf8) { + header->flags |= android::ResStringPool_header::UTF8_FLAG; + } + + uint32_t* indices = pool.size() != 0 ? out->NextBlock<uint32_t>(pool.size()) : nullptr; + uint32_t* style_indices = + pool.styles_.size() != 0 ? out->NextBlock<uint32_t>(pool.styles_.size()) : nullptr; + + const size_t before_strings_index = out->size(); + header->stringsStart = before_strings_index - start_index; + + // Styles always come first. + for (const std::unique_ptr<StyleEntry>& entry : pool.styles_) { + *indices++ = out->size() - before_strings_index; + no_error = EncodeString(entry->value, utf8, out, diag) && no_error; + } + + for (const std::unique_ptr<Entry>& entry : pool.strings_) { + *indices++ = out->size() - before_strings_index; + no_error = EncodeString(entry->value, utf8, out, diag) && no_error; + } + + out->Align4(); + + if (style_indices != nullptr) { + const size_t before_styles_index = out->size(); + header->stylesStart = util::HostToDevice32(before_styles_index - start_index); + + for (const std::unique_ptr<StyleEntry>& entry : pool.styles_) { + *style_indices++ = out->size() - before_styles_index; + + if (!entry->spans.empty()) { + android::ResStringPool_span* span = + out->NextBlock<android::ResStringPool_span>(entry->spans.size()); + for (const Span& s : entry->spans) { + span->name.index = util::HostToDevice32(s.name.index()); + span->firstChar = util::HostToDevice32(s.first_char); + span->lastChar = util::HostToDevice32(s.last_char); + span++; + } + } + + uint32_t* spanEnd = out->NextBlock<uint32_t>(); + *spanEnd = android::ResStringPool_span::END; + } + + // The error checking code in the platform looks for an entire + // ResStringPool_span structure worth of 0xFFFFFFFF at the end + // of the style block, so fill in the remaining 2 32bit words + // with 0xFFFFFFFF. + const size_t padding_length = + sizeof(android::ResStringPool_span) - sizeof(android::ResStringPool_span::name); + uint8_t* padding = out->NextBlock<uint8_t>(padding_length); + memset(padding, 0xff, padding_length); + out->Align4(); + } + header->header.size = util::HostToDevice32(out->size() - start_index); + return no_error; +} + +bool StringPool::FlattenUtf8(BigBuffer* out, const StringPool& pool, IDiagnostics* diag) { + return Flatten(out, pool, true, diag); +} + +bool StringPool::FlattenUtf16(BigBuffer* out, const StringPool& pool, IDiagnostics* diag) { + return Flatten(out, pool, false, diag); +} + +} // namespace android diff --git a/libs/androidfw/Util.cpp b/libs/androidfw/Util.cpp index 59c9d640bb91..52ad0dce8187 100644 --- a/libs/androidfw/Util.cpp +++ b/libs/androidfw/Util.cpp @@ -68,6 +68,108 @@ std::string Utf16ToUtf8(const StringPiece16& utf16) { return utf8; } +std::string Utf8ToModifiedUtf8(const std::string& utf8) { + // Java uses Modified UTF-8 which only supports the 1, 2, and 3 byte formats of UTF-8. To encode + // 4 byte UTF-8 codepoints, Modified UTF-8 allows the use of surrogate pairs in the same format + // of CESU-8 surrogate pairs. Calculate the size of the utf8 string with all 4 byte UTF-8 + // codepoints replaced with 2 3 byte surrogate pairs + size_t modified_size = 0; + const size_t size = utf8.size(); + for (size_t i = 0; i < size; i++) { + if (((uint8_t)utf8[i] >> 4) == 0xF) { + modified_size += 6; + i += 3; + } else { + modified_size++; + } + } + + // Early out if no 4 byte codepoints are found + if (size == modified_size) { + return utf8; + } + + std::string output; + output.reserve(modified_size); + for (size_t i = 0; i < size; i++) { + if (((uint8_t)utf8[i] >> 4) == 0xF) { + int32_t codepoint = utf32_from_utf8_at(utf8.data(), size, i, nullptr); + + // Calculate the high and low surrogates as UTF-16 would + int32_t high = ((codepoint - 0x10000) / 0x400) + 0xD800; + int32_t low = ((codepoint - 0x10000) % 0x400) + 0xDC00; + + // Encode each surrogate in UTF-8 + output.push_back((char)(0xE4 | ((high >> 12) & 0xF))); + output.push_back((char)(0x80 | ((high >> 6) & 0x3F))); + output.push_back((char)(0x80 | (high & 0x3F))); + output.push_back((char)(0xE4 | ((low >> 12) & 0xF))); + output.push_back((char)(0x80 | ((low >> 6) & 0x3F))); + output.push_back((char)(0x80 | (low & 0x3F))); + i += 3; + } else { + output.push_back(utf8[i]); + } + } + + return output; +} + +std::string ModifiedUtf8ToUtf8(const std::string& modified_utf8) { + // The UTF-8 representation will have a byte length less than or equal to the Modified UTF-8 + // representation. + std::string output; + output.reserve(modified_utf8.size()); + + size_t index = 0; + const size_t modified_size = modified_utf8.size(); + while (index < modified_size) { + size_t next_index; + int32_t high_surrogate = + utf32_from_utf8_at(modified_utf8.data(), modified_size, index, &next_index); + if (high_surrogate < 0) { + return {}; + } + + // Check that the first codepoint is within the high surrogate range + if (high_surrogate >= 0xD800 && high_surrogate <= 0xDB7F) { + int32_t low_surrogate = + utf32_from_utf8_at(modified_utf8.data(), modified_size, next_index, &next_index); + if (low_surrogate < 0) { + return {}; + } + + // Check that the second codepoint is within the low surrogate range + if (low_surrogate >= 0xDC00 && low_surrogate <= 0xDFFF) { + const char32_t codepoint = + (char32_t)(((high_surrogate - 0xD800) * 0x400) + (low_surrogate - 0xDC00) + 0x10000); + + // The decoded codepoint should represent a 4 byte, UTF-8 character + const size_t utf8_length = (size_t)utf32_to_utf8_length(&codepoint, 1); + if (utf8_length != 4) { + return {}; + } + + // Encode the UTF-8 representation of the codepoint into the string + const size_t start_index = output.size(); + output.resize(start_index + utf8_length); + char* start = &output[start_index]; + utf32_to_utf8((char32_t*)&codepoint, 1, start, utf8_length + 1); + + index = next_index; + continue; + } + } + + // Append non-surrogate pairs to the output string + for (size_t i = index; i < next_index; i++) { + output.push_back(modified_utf8[i]); + } + index = next_index; + } + return output; +} + static std::vector<std::string> SplitAndTransform( const StringPiece& str, char sep, const std::function<char(char)>& f) { std::vector<std::string> parts; @@ -90,6 +192,29 @@ std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep) { return SplitAndTransform(str, sep, ::tolower); } +std::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer) { + std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]); + uint8_t* p = data.get(); + for (const auto& block : buffer) { + memcpy(p, block.buffer.get(), block.size); + p += block.size; + } + return data; +} + +StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx) { + if (auto str = pool.stringAt(idx); str.ok()) { + return *str; + } + return StringPiece16(); +} + +std::string GetString(const android::ResStringPool& pool, size_t idx) { + if (auto str = pool.string8At(idx); str.ok()) { + return ModifiedUtf8ToUtf8(str->to_string()); + } + return Utf16ToUtf8(GetString16(pool, idx)); +} } // namespace util } // namespace android diff --git a/libs/androidfw/include/androidfw/BigBuffer.h b/libs/androidfw/include/androidfw/BigBuffer.h new file mode 100644 index 000000000000..b99a4edf9d88 --- /dev/null +++ b/libs/androidfw/include/androidfw/BigBuffer.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_BIG_BUFFER_H +#define _ANDROID_BIG_BUFFER_H + +#include <cstring> +#include <memory> +#include <string> +#include <type_traits> +#include <vector> + +#include "android-base/logging.h" +#include "android-base/macros.h" + +namespace android { + +/** + * Inspired by protobuf's ZeroCopyOutputStream, offers blocks of memory + * in which to write without knowing the full size of the entire payload. + * This is essentially a list of memory blocks. As one fills up, another + * block is allocated and appended to the end of the list. + */ +class BigBuffer { + public: + /** + * A contiguous block of allocated memory. + */ + struct Block { + /** + * Pointer to the memory. + */ + std::unique_ptr<uint8_t[]> buffer; + + /** + * Size of memory that is currently occupied. The actual + * allocation may be larger. + */ + size_t size; + + private: + friend class BigBuffer; + + /** + * The size of the memory block allocation. + */ + size_t block_size_; + }; + + typedef std::vector<Block>::const_iterator const_iterator; + + /** + * Create a BigBuffer with block allocation sizes + * of block_size. + */ + explicit BigBuffer(size_t block_size); + + BigBuffer(BigBuffer&& rhs) noexcept; + + /** + * Number of occupied bytes in all the allocated blocks. + */ + size_t size() const; + + /** + * Returns a pointer to an array of T, where T is + * a POD type. The elements are zero-initialized. + */ + template <typename T> + T* NextBlock(size_t count = 1); + + /** + * Returns the next block available and puts the size in out_count. + * This is useful for grabbing blocks where the size doesn't matter. + * Use BackUp() to give back any bytes that were not used. + */ + void* NextBlock(size_t* out_count); + + /** + * Backs up count bytes. This must only be called after NextBlock() + * and can not be larger than sizeof(T) * count of the last NextBlock() + * call. + */ + void BackUp(size_t count); + + /** + * Moves the specified BigBuffer into this one. When this method + * returns, buffer is empty. + */ + void AppendBuffer(BigBuffer&& buffer); + + /** + * Pads the block with 'bytes' bytes of zero values. + */ + void Pad(size_t bytes); + + /** + * Pads the block so that it aligns on a 4 byte boundary. + */ + void Align4(); + + size_t block_size() const; + + const_iterator begin() const; + const_iterator end() const; + + std::string to_string() const; + + private: + DISALLOW_COPY_AND_ASSIGN(BigBuffer); + + /** + * Returns a pointer to a buffer of the requested size. + * The buffer is zero-initialized. + */ + void* NextBlockImpl(size_t size); + + size_t block_size_; + size_t size_; + std::vector<Block> blocks_; +}; + +inline BigBuffer::BigBuffer(size_t block_size) : block_size_(block_size), size_(0) { +} + +inline BigBuffer::BigBuffer(BigBuffer&& rhs) noexcept + : block_size_(rhs.block_size_), size_(rhs.size_), blocks_(std::move(rhs.blocks_)) { +} + +inline size_t BigBuffer::size() const { + return size_; +} + +inline size_t BigBuffer::block_size() const { + return block_size_; +} + +template <typename T> +inline T* BigBuffer::NextBlock(size_t count) { + static_assert(std::is_standard_layout<T>::value, "T must be standard_layout type"); + CHECK(count != 0); + return reinterpret_cast<T*>(NextBlockImpl(sizeof(T) * count)); +} + +inline void BigBuffer::BackUp(size_t count) { + Block& block = blocks_.back(); + block.size -= count; + size_ -= count; +} + +inline void BigBuffer::AppendBuffer(BigBuffer&& buffer) { + std::move(buffer.blocks_.begin(), buffer.blocks_.end(), std::back_inserter(blocks_)); + size_ += buffer.size_; + buffer.blocks_.clear(); + buffer.size_ = 0; +} + +inline void BigBuffer::Pad(size_t bytes) { + NextBlock<char>(bytes); +} + +inline void BigBuffer::Align4() { + const size_t unaligned = size_ % 4; + if (unaligned != 0) { + Pad(4 - unaligned); + } +} + +inline BigBuffer::const_iterator BigBuffer::begin() const { + return blocks_.begin(); +} + +inline BigBuffer::const_iterator BigBuffer::end() const { + return blocks_.end(); +} + +} // namespace android + +#endif // _ANDROID_BIG_BUFFER_H diff --git a/libs/androidfw/include/androidfw/IDiagnostics.h b/libs/androidfw/include/androidfw/IDiagnostics.h new file mode 100644 index 000000000000..273b05ac7689 --- /dev/null +++ b/libs/androidfw/include/androidfw/IDiagnostics.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_DIAGNOSTICS_H +#define _ANDROID_DIAGNOSTICS_H + +#include <sstream> +#include <string> + +#include "Source.h" +#include "android-base/macros.h" +#include "androidfw/StringPiece.h" + +namespace android { + +struct DiagMessageActual { + Source source; + std::string message; +}; + +struct DiagMessage { + public: + DiagMessage() = default; + + explicit DiagMessage(const android::StringPiece& src) : source_(src) { + } + + explicit DiagMessage(const Source& src) : source_(src) { + } + + explicit DiagMessage(size_t line) : source_(Source().WithLine(line)) { + } + + template <typename T> + DiagMessage& operator<<(const T& value) { + message_ << value; + return *this; + } + + DiagMessageActual Build() const { + return DiagMessageActual{source_, message_.str()}; + } + + private: + Source source_; + std::stringstream message_; +}; + +template <> +inline DiagMessage& DiagMessage::operator<<(const ::std::u16string& value) { + message_ << android::StringPiece16(value); + return *this; +} + +struct IDiagnostics { + virtual ~IDiagnostics() = default; + + enum class Level { Note, Warn, Error }; + + virtual void Log(Level level, DiagMessageActual& actualMsg) = 0; + + virtual void Error(const DiagMessage& message) { + DiagMessageActual actual = message.Build(); + Log(Level::Error, actual); + } + + virtual void Warn(const DiagMessage& message) { + DiagMessageActual actual = message.Build(); + Log(Level::Warn, actual); + } + + virtual void Note(const DiagMessage& message) { + DiagMessageActual actual = message.Build(); + Log(Level::Note, actual); + } +}; + +class SourcePathDiagnostics : public IDiagnostics { + public: + SourcePathDiagnostics(const Source& src, IDiagnostics* diag) : source_(src), diag_(diag) { + } + + void Log(Level level, DiagMessageActual& actual_msg) override { + actual_msg.source.path = source_.path; + diag_->Log(level, actual_msg); + if (level == Level::Error) { + error = true; + } + } + + bool HadError() { + return error; + } + + private: + Source source_; + IDiagnostics* diag_; + bool error = false; + + DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics); +}; + +class NoOpDiagnostics : public IDiagnostics { + public: + NoOpDiagnostics() = default; + + void Log(Level level, DiagMessageActual& actual_msg) override { + (void)level; + (void)actual_msg; + } + + DISALLOW_COPY_AND_ASSIGN(NoOpDiagnostics); +}; + +} // namespace android + +#endif /* _ANDROID_DIAGNOSTICS_H */ diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h index 6804472b3d17..a1cbbbf2271b 100644 --- a/libs/androidfw/include/androidfw/Idmap.h +++ b/libs/androidfw/include/androidfw/Idmap.h @@ -23,6 +23,7 @@ #include <variant> #include "android-base/macros.h" +#include "androidfw/ConfigDescription.h" #include "androidfw/StringPiece.h" #include "androidfw/ResourceTypes.h" #include "utils/ByteOrder.h" @@ -35,6 +36,7 @@ struct Idmap_header; struct Idmap_data_header; struct Idmap_target_entry; struct Idmap_target_entry_inline; +struct Idmap_target_entry_inline_value; struct Idmap_overlay_entry; // A string pool for overlay apk assets. The string pool holds the strings of the overlay resources @@ -91,7 +93,8 @@ class IdmapResMap { public: Result() = default; explicit Result(uint32_t value) : data_(value) {}; - explicit Result(const Res_value& value) : data_(value) { }; + explicit Result(const std::map<ConfigDescription, Res_value> &value) + : data_(value) { }; // Returns `true` if the resource is overlaid. explicit operator bool() const { @@ -107,15 +110,16 @@ class IdmapResMap { } bool IsInlineValue() const { - return std::get_if<Res_value>(&data_) != nullptr; + return std::get_if<2>(&data_) != nullptr; } - const Res_value& GetInlineValue() const { - return std::get<Res_value>(data_); + const std::map<ConfigDescription, Res_value>& GetInlineValue() const { + return std::get<2>(data_); } private: - std::variant<std::monostate, uint32_t, Res_value> data_; + std::variant<std::monostate, uint32_t, + std::map<ConfigDescription, Res_value> > data_; }; // Looks up the value that overlays the target resource id. @@ -129,12 +133,16 @@ class IdmapResMap { explicit IdmapResMap(const Idmap_data_header* data_header, const Idmap_target_entry* entries, const Idmap_target_entry_inline* inline_entries, + const Idmap_target_entry_inline_value* inline_entry_values, + const ConfigDescription* configs, uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table); const Idmap_data_header* data_header_; const Idmap_target_entry* entries_; const Idmap_target_entry_inline* inline_entries_; + const Idmap_target_entry_inline_value* inline_entry_values_; + const ConfigDescription* configurations_; const uint8_t target_assigned_package_id_; const OverlayDynamicRefTable* overlay_ref_table_; @@ -170,8 +178,8 @@ class LoadedIdmap { // Returns a mapping from target resource ids to overlay values. const IdmapResMap GetTargetResourcesMap(uint8_t target_assigned_package_id, const OverlayDynamicRefTable* overlay_ref_table) const { - return IdmapResMap(data_header_, target_entries_, target_inline_entries_, - target_assigned_package_id, overlay_ref_table); + return IdmapResMap(data_header_, target_entries_, target_inline_entries_, inline_entry_values_, + configurations_, target_assigned_package_id, overlay_ref_table); } // Returns a dynamic reference table for a loaded overlay package. @@ -191,6 +199,8 @@ class LoadedIdmap { const Idmap_data_header* data_header_; const Idmap_target_entry* target_entries_; const Idmap_target_entry_inline* target_inline_entries_; + const Idmap_target_entry_inline_value* inline_entry_values_; + const ConfigDescription* configurations_; const Idmap_overlay_entry* overlay_entries_; const std::unique_ptr<ResStringPool> string_pool_; @@ -207,6 +217,8 @@ class LoadedIdmap { const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, const Idmap_target_entry_inline* target_inline_entries, + const Idmap_target_entry_inline_value* inline_entry_values_, + const ConfigDescription* configs, const Idmap_overlay_entry* overlay_entries, std::unique_ptr<ResStringPool>&& string_pool, std::string_view overlay_apk_path, diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h index b3d6a4dcb955..e45963950b04 100644 --- a/libs/androidfw/include/androidfw/LoadedArsc.h +++ b/libs/androidfw/include/androidfw/LoadedArsc.h @@ -314,6 +314,8 @@ class LoadedArsc { const LoadedIdmap* loaded_idmap = nullptr, package_property_t property_flags = 0U); + static std::unique_ptr<LoadedArsc> Load(const LoadedIdmap* loaded_idmap = nullptr); + // Create an empty LoadedArsc. This is used when an APK has no resources.arsc. static std::unique_ptr<LoadedArsc> CreateEmpty(); @@ -338,6 +340,7 @@ class LoadedArsc { LoadedArsc() = default; bool LoadTable( const Chunk& chunk, const LoadedIdmap* loaded_idmap, package_property_t property_flags); + bool LoadStringPool(const LoadedIdmap* loaded_idmap); std::unique_ptr<ResStringPool> global_string_pool_ = util::make_unique<ResStringPool>(); std::vector<std::unique_ptr<const LoadedPackage>> packages_; diff --git a/libs/androidfw/include/androidfw/ResourceTimer.h b/libs/androidfw/include/androidfw/ResourceTimer.h new file mode 100644 index 000000000000..74613519a920 --- /dev/null +++ b/libs/androidfw/include/androidfw/ResourceTimer.h @@ -0,0 +1,221 @@ +/* + * 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. + */ + +#ifndef ANDROIDFW_RESOURCETIMER_H_ +#define ANDROIDFW_RESOURCETIMER_H_ + +#include <time.h> +#include <atomic> +#include <vector> + +#include <utils/Mutex.h> +#include <android-base/macros.h> +#include <androidfw/Util.h> + +namespace android { + +// ResourceTimer captures the duration of short functions. Durations are accumulated in registers +// and statistics are pulled back to the Java layer as needed. +// To monitor an API, first add it to the Counter enumeration. Then, inside the API, create an +// instance of ResourceTimer with the appropriate enumeral. The corresponding counter will be +// updated when the ResourceTimer destructor is called, normally at the end of the enclosing block. +class ResourceTimer { + public: + enum class Counter { + GetResourceValue, + RetrieveAttributes, + + LastCounter = RetrieveAttributes, + }; + static const int counterSize = static_cast<int>(Counter::LastCounter) + 1; + static char const *toString(Counter); + + // Start a timer for the specified counter. + ResourceTimer(Counter); + // The block is exiting. If the timer is active, record it. + ~ResourceTimer(); + // This records the elapsed time and disables further recording. Use this if the containing + // block includes extra processing that should not be included in the timer. The method is + // destructive in that the timer is no longer valid and further calls to record() will be + // ignored. + void record(); + // This cancels a timer. Elapsed time will neither be computed nor recorded. + void cancel(); + + // A single timer contains the count of events and the cumulative time spent handling the + // events. It also includes the smallest value seen and 10 largest values seen. Finally, it + // includes a histogram of values that approximates a semi-log. + + // The timer can compute percentiles of recorded events. For example, the p50 value is a time + // such that 50% of the readings are below the value and 50% are above the value. The + // granularity in the readings means that a percentile cannot always be computed. In this case, + // the percentile is reported as zero. (The simplest example is when there is a single + // reading.) Even if the value can be computed, it will not be exact. Therefore, a percentile + // is actually reported as two values: the lowest time at which it might be valid and the + // highest time at which it might be valid. + struct Timer { + static const size_t MaxLargest = 5; + + // The construct zeros all the fields. The destructor releases memory allocated to the + // buckets. + Timer(); + ~Timer(); + + // The following summary values are set to zero on a reset. All times are in ns. + + // The total number of events recorded. + int count; + // The total duration of events. + int64_t total; + // The smallest event duration seen. This is guaranteed to be non-zero if count is greater + // than 0. + int mintime; + // The largest event duration seen. + int maxtime; + + // The largest values seen. Element 0 is the largest value seen (and is the same as maxtime, + // above). Element 1 is the next largest, and so on. If count is less than MaxLargest, + // unused elements will be zero. + int largest[MaxLargest]; + + // The p50 value is a time such that 50% of the readings are below that time and 50% of the + // readings. + + // A single percentile is defined by the lowest value supported by the readings and the + // highest value supported by the readings. + struct Percentile { + // The nominal time (in ns) of the percentile. The true percentile is guaranteed to be less + // than or equal to this time. + int nominal; + // The actual percentile of the nominal time. + int nominal_actual; + // The time of the next lower bin. The true percentile is guaranteed to be greater than + // this time. + int floor; + // The actual percentile of the floor time. + int floor_actual; + + // Fill in a percentile given the cumulative to the bin, the count in the current bin, the + // total count, the width of the bin, and the time of the bin. + void compute(int cumulative, int current, int count, int width, int time); + }; + + // The structure that holds the percentiles. + struct { + Percentile p50; + Percentile p90; + Percentile p95; + Percentile p99; + } pvalues; + + // Set all counters to zero. + void reset(); + // Record an event. The input time is in ns. + void record(int); + // Compute the percentiles. Percentiles are computed on demand, as the computation is too + // expensive to be done inline. + void compute(); + + // Copy one timer to another. If reset is true then the src is reset immediately after the + // copy. The reset flag is exploited to make the copy faster. Any data in dst is lost. + static void copy(Timer &dst, Timer &src, bool reset); + + private: + // Free any buckets. + void freeBuckets(); + + // Readings are placed in bins, which are orgzanized into decades. The decade 0 covers + // [0,100) in steps of 1us. Decade 1 covers [0,1000) in steps of 10us. Decade 2 covers + // [0,10000) in steps of 100us. And so on. + + // An event is placed in the first bin that can hold it. This means that events in the range + // of [0,100) are placed in the first decade, events in the range of [0,1000) are placed in + // the second decade, and so on. This also means that the first 10% of the bins are unused + // in each decade after the first. + + // The design provides at least two significant digits across the range of [0,10000). + + static const size_t MaxDimension = 4; + static const size_t MaxBuckets = 100; + + // The range of each dimension. The lower value is always zero. + static const int range[MaxDimension]; + // The width of each bin, by dimension + static const int width[MaxDimension]; + + // A histogram of the values seen. Centuries are allocated as needed, to minimize the memory + // impact. + int *buckets[MaxDimension]; + }; + + // Fetch one Timer. The function has a short-circuit behavior: if the count is zero then + // destination count is set to zero and the function returns false. Otherwise, the destination + // is a copy of the source and the function returns true. This behavior lowers the cost of + // handling unused timers. + static bool copy(int src, Timer &dst, bool reset); + + // Enable the timers. Timers are initially disabled. Enabling timers allocates memory for the + // counters. Timers cannot be disabled. + static void enable(); + + private: + // An internal reset method. This does not take a lock. + static void reset(); + + // Helper method to convert a counter into an enum. Presumably, this will be inlined into zero + // actual cpu instructions. + static inline std::vector<unsigned int>::size_type toIndex(Counter c) { + return static_cast<std::vector<unsigned int>::size_type>(c); + } + + // Every counter has an associated lock. The lock has been factored into a separate class to + // keep the Timer class a POD. + struct GuardedTimer { + Mutex lock_; + Timer timer_; + }; + + // Scoped timer + struct ScopedTimer { + AutoMutex _l; + Timer &t; + ScopedTimer(GuardedTimer &g) : + _l(g.lock_), t(g.timer_) { + } + Timer *operator->() { + return &t; + } + Timer& operator*() { + return t; + } + }; + + // An individual timer is active (or not), is tracking a specific API, and has a start time. + // The api and the start time are undefined if the timer is not active. + bool active_; + Counter api_; + struct timespec start_; + + // The global enable flag. This is initially false and may be set true by the java runtime. + static std::atomic<bool> enabled_; + + // The global timers. The memory for the timers is not allocated until the timers are enabled. + static std::atomic<GuardedTimer *> counter_; +}; + +} // namespace android + +#endif /* ANDROIDFW_RESOURCETIMER_H_ */ diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 3d66244646d5..9309091f4124 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -45,7 +45,7 @@ namespace android { constexpr const uint32_t kIdmapMagic = 0x504D4449u; -constexpr const uint32_t kIdmapCurrentVersion = 0x00000008u; +constexpr const uint32_t kIdmapCurrentVersion = 0x00000009u; // This must never change. constexpr const uint32_t kFabricatedOverlayMagic = 0x4f525246; // FRRO (big endian) @@ -53,7 +53,7 @@ constexpr const uint32_t kFabricatedOverlayMagic = 0x4f525246; // FRRO (big endi // The version should only be changed when a backwards-incompatible change must be made to the // fabricated overlay file format. Old fabricated overlays must be migrated to the new file format // to prevent losing fabricated overlay data. -constexpr const uint32_t kFabricatedOverlayCurrentVersion = 1; +constexpr const uint32_t kFabricatedOverlayCurrentVersion = 2; // Returns whether or not the path represents a fabricated overlay. bool IsFabricatedOverlay(const std::string& path); @@ -1098,7 +1098,7 @@ struct ResTable_config SDKVERSION_ANY = 0 }; - enum { + enum { MINORVERSION_ANY = 0 }; diff --git a/libs/androidfw/include/androidfw/Source.h b/libs/androidfw/include/androidfw/Source.h new file mode 100644 index 000000000000..0421a91d3eba --- /dev/null +++ b/libs/androidfw/include/androidfw/Source.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SOURCE_H +#define _ANDROID_SOURCE_H + +#include <optional> +#include <ostream> +#include <string> + +#include "android-base/stringprintf.h" +#include "androidfw/StringPiece.h" + +namespace android { + +// Represents a file on disk. Used for logging and showing errors. +struct Source { + std::string path; + std::optional<size_t> line; + std::optional<std::string> archive; + + Source() = default; + + inline Source(const android::StringPiece& path) : path(path.to_string()) { // NOLINT(implicit) + } + + inline Source(const android::StringPiece& path, const android::StringPiece& archive) + : path(path.to_string()), archive(archive.to_string()) { + } + + inline Source(const android::StringPiece& path, size_t line) + : path(path.to_string()), line(line) { + } + + inline Source WithLine(size_t line) const { + return Source(path, line); + } + + std::string to_string() const { + std::string s = path; + if (archive) { + s = ::android::base::StringPrintf("%s@%s", archive.value().c_str(), s.c_str()); + } + if (line) { + s = ::android::base::StringPrintf("%s:%zd", s.c_str(), line.value()); + } + return s; + } +}; + +// +// Implementations +// + +inline ::std::ostream& operator<<(::std::ostream& out, const Source& source) { + return out << source.to_string(); +} + +inline bool operator==(const Source& lhs, const Source& rhs) { + return lhs.path == rhs.path && lhs.line == rhs.line; +} + +inline bool operator<(const Source& lhs, const Source& rhs) { + int cmp = lhs.path.compare(rhs.path); + if (cmp < 0) return true; + if (cmp > 0) return false; + if (lhs.line) { + if (rhs.line) { + return lhs.line.value() < rhs.line.value(); + } + return false; + } + return bool(rhs.line); +} + +} // namespace android + +#endif // _ANDROID_SOURCE_H diff --git a/libs/androidfw/include/androidfw/StringPiece.h b/libs/androidfw/include/androidfw/StringPiece.h index 921877dc4982..fac2fa4fa575 100644 --- a/libs/androidfw/include/androidfw/StringPiece.h +++ b/libs/androidfw/include/androidfw/StringPiece.h @@ -288,12 +288,12 @@ inline ::std::basic_string<TChar>& operator+=(::std::basic_string<TChar>& lhs, template <typename TChar> inline bool operator==(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) { - return rhs == lhs; + return BasicStringPiece<TChar>(lhs) == rhs; } template <typename TChar> inline bool operator!=(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) { - return rhs != lhs; + return BasicStringPiece<TChar>(lhs) != rhs; } } // namespace android diff --git a/libs/androidfw/include/androidfw/StringPool.h b/libs/androidfw/include/androidfw/StringPool.h new file mode 100644 index 000000000000..25174d8fe3c8 --- /dev/null +++ b/libs/androidfw/include/androidfw/StringPool.h @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_STRING_POOL_H +#define _ANDROID_STRING_POOL_H + +#include <functional> +#include <memory> +#include <string> +#include <unordered_map> +#include <vector> + +#include "BigBuffer.h" +#include "IDiagnostics.h" +#include "android-base/macros.h" +#include "androidfw/ConfigDescription.h" +#include "androidfw/StringPiece.h" + +namespace android { + +struct Span { + std::string name; + uint32_t first_char; + uint32_t last_char; + + bool operator==(const Span& right) const { + return name == right.name && first_char == right.first_char && last_char == right.last_char; + } +}; + +struct StyleString { + std::string str; + std::vector<Span> spans; +}; + +// A StringPool for storing the value of String and StyledString resources. +// Styles and Strings are stored separately, since the runtime variant of this +// class -- ResStringPool -- requires that styled strings *always* appear first, since their +// style data is stored as an array indexed by the same indices as the main string pool array. +// Otherwise, the style data array would have to be sparse and take up more space. +class StringPool { + public: + using size_type = size_t; + + class Context { + public: + enum : uint32_t { + kHighPriority = 1u, + kNormalPriority = 0x7fffffffu, + kLowPriority = 0xffffffffu, + }; + uint32_t priority = kNormalPriority; + android::ConfigDescription config; + + Context() = default; + Context(uint32_t p, const android::ConfigDescription& c) : priority(p), config(c) { + } + explicit Context(uint32_t p) : priority(p) { + } + explicit Context(const android::ConfigDescription& c) : priority(kNormalPriority), config(c) { + } + }; + + class Entry; + + class Ref { + public: + Ref(); + Ref(const Ref&); + ~Ref(); + + Ref& operator=(const Ref& rhs); + bool operator==(const Ref& rhs) const; + bool operator!=(const Ref& rhs) const; + const std::string* operator->() const; + const std::string& operator*() const; + + size_t index() const; + const Context& GetContext() const; + + private: + friend class StringPool; + + explicit Ref(Entry* entry); + + Entry* entry_; + }; + + class StyleEntry; + + class StyleRef { + public: + StyleRef(); + StyleRef(const StyleRef&); + ~StyleRef(); + + StyleRef& operator=(const StyleRef& rhs); + bool operator==(const StyleRef& rhs) const; + bool operator!=(const StyleRef& rhs) const; + const StyleEntry* operator->() const; + const StyleEntry& operator*() const; + + size_t index() const; + const Context& GetContext() const; + + private: + friend class StringPool; + + explicit StyleRef(StyleEntry* entry); + + StyleEntry* entry_; + }; + + class Entry { + public: + std::string value; + Context context; + + private: + friend class StringPool; + friend class Ref; + + size_t index_; + int ref_; + const StringPool* pool_; + }; + + struct Span { + Ref name; + uint32_t first_char; + uint32_t last_char; + }; + + class StyleEntry { + public: + std::string value; + Context context; + std::vector<Span> spans; + + private: + friend class StringPool; + friend class StyleRef; + + size_t index_; + int ref_; + }; + + static bool FlattenUtf8(BigBuffer* out, const StringPool& pool, IDiagnostics* diag); + static bool FlattenUtf16(BigBuffer* out, const StringPool& pool, IDiagnostics* diag); + + StringPool() = default; + StringPool(StringPool&&) = default; + StringPool& operator=(StringPool&&) = default; + + // Adds a string to the pool, unless it already exists. Returns a reference to the string in the + // pool. + Ref MakeRef(const android::StringPiece& str); + + // Adds a string to the pool, unless it already exists, with a context object that can be used + // when sorting the string pool. Returns a reference to the string in the pool. + Ref MakeRef(const android::StringPiece& str, const Context& context); + + // Adds a string from another string pool. Returns a reference to the string in the string pool. + Ref MakeRef(const Ref& ref); + + // Adds a style to the string pool and returns a reference to it. + StyleRef MakeRef(const StyleString& str); + + // Adds a style to the string pool with a context object that can be used when sorting the string + // pool. Returns a reference to the style in the string pool. + StyleRef MakeRef(const StyleString& str, const Context& context); + + // Adds a style from another string pool. Returns a reference to the style in the string pool. + StyleRef MakeRef(const StyleRef& ref); + + // Moves pool into this one without coalescing strings. When this function returns, pool will be + // empty. + void Merge(StringPool&& pool); + + inline const std::vector<std::unique_ptr<Entry>>& strings() const { + return strings_; + } + + // Returns the number of strings in the table. + inline size_t size() const { + return styles_.size() + strings_.size(); + } + + // Reserves space for strings and styles as an optimization. + void HintWillAdd(size_t string_count, size_t style_count); + + // Sorts the strings according to their Context using some comparison function. + // Equal Contexts are further sorted by string value, lexicographically. + // If no comparison function is provided, values are only sorted lexicographically. + void Sort(const std::function<int(const Context&, const Context&)>& cmp = nullptr); + + // Removes any strings that have no references. + void Prune(); + + private: + DISALLOW_COPY_AND_ASSIGN(StringPool); + + static bool Flatten(BigBuffer* out, const StringPool& pool, bool utf8, IDiagnostics* diag); + + Ref MakeRefImpl(const android::StringPiece& str, const Context& context, bool unique); + void ReAssignIndices(); + + std::vector<std::unique_ptr<Entry>> strings_; + std::vector<std::unique_ptr<StyleEntry>> styles_; + std::unordered_multimap<android::StringPiece, Entry*> indexed_strings_; +}; + +} // namespace android + +#endif // _ANDROID_STRING_POOL_H diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h index c59b5b6c51a2..1bbc7f5716bc 100644 --- a/libs/androidfw/include/androidfw/Util.h +++ b/libs/androidfw/include/androidfw/Util.h @@ -17,15 +17,18 @@ #ifndef UTIL_H_ #define UTIL_H_ +#include <android-base/macros.h> +#include <util/map_ptr.h> + #include <cstdlib> #include <memory> #include <sstream> #include <vector> -#include <android-base/macros.h> -#include <util/map_ptr.h> - +#include "androidfw/BigBuffer.h" +#include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" +#include "utils/ByteOrder.h" #ifdef __ANDROID__ #define ANDROID_LOG(x) LOG(x) @@ -125,6 +128,28 @@ std::u16string Utf8ToUtf16(const StringPiece& utf8); // Converts a UTF-16 string to a UTF-8 string. std::string Utf16ToUtf8(const StringPiece16& utf16); +// Converts a UTF8 string into Modified UTF8 +std::string Utf8ToModifiedUtf8(const std::string& utf8); + +// Converts a Modified UTF8 string into a UTF8 string +std::string ModifiedUtf8ToUtf8(const std::string& modified_utf8); + +inline uint16_t HostToDevice16(uint16_t value) { + return htods(value); +} + +inline uint32_t HostToDevice32(uint32_t value) { + return htodl(value); +} + +inline uint16_t DeviceToHost16(uint16_t value) { + return dtohs(value); +} + +inline uint32_t DeviceToHost32(uint32_t value) { + return dtohl(value); +} + std::vector<std::string> SplitAndLowercase(const android::StringPiece& str, char sep); template <typename T> @@ -136,6 +161,18 @@ inline bool IsFourByteAligned(const void* data) { return ((size_t)data & 0x3U) == 0; } +// Helper method to extract a UTF-16 string from a StringPool. If the string is stored as UTF-8, +// the conversion to UTF-16 happens within ResStringPool. +android::StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx); + +// Helper method to extract a UTF-8 string from a StringPool. If the string is stored as UTF-16, +// the conversion from UTF-16 to UTF-8 does not happen in ResStringPool and is done by this method, +// which maintains no state or cache. This means we must return an std::string copy. +std::string GetString(const android::ResStringPool& pool, size_t idx); + +// Copies the entire BigBuffer into a single buffer. +std::unique_ptr<uint8_t[]> Copy(const android::BigBuffer& buffer); + } // namespace util } // namespace android diff --git a/libs/androidfw/tests/BigBuffer_test.cpp b/libs/androidfw/tests/BigBuffer_test.cpp new file mode 100644 index 000000000000..382d21e20846 --- /dev/null +++ b/libs/androidfw/tests/BigBuffer_test.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "androidfw/BigBuffer.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using ::testing::NotNull; + +namespace android { + +TEST(BigBufferTest, AllocateSingleBlock) { + BigBuffer buffer(4); + + EXPECT_THAT(buffer.NextBlock<char>(2), NotNull()); + EXPECT_EQ(2u, buffer.size()); +} + +TEST(BigBufferTest, ReturnSameBlockIfNextAllocationFits) { + BigBuffer buffer(16); + + char* b1 = buffer.NextBlock<char>(8); + EXPECT_THAT(b1, NotNull()); + + char* b2 = buffer.NextBlock<char>(4); + EXPECT_THAT(b2, NotNull()); + + EXPECT_EQ(b1 + 8, b2); +} + +TEST(BigBufferTest, AllocateExactSizeBlockIfLargerThanBlockSize) { + BigBuffer buffer(16); + + EXPECT_THAT(buffer.NextBlock<char>(32), NotNull()); + EXPECT_EQ(32u, buffer.size()); +} + +TEST(BigBufferTest, AppendAndMoveBlock) { + BigBuffer buffer(16); + + uint32_t* b1 = buffer.NextBlock<uint32_t>(); + ASSERT_THAT(b1, NotNull()); + *b1 = 33; + + { + BigBuffer buffer2(16); + b1 = buffer2.NextBlock<uint32_t>(); + ASSERT_THAT(b1, NotNull()); + *b1 = 44; + + buffer.AppendBuffer(std::move(buffer2)); + EXPECT_EQ(0u, buffer2.size()); // NOLINT + EXPECT_EQ(buffer2.begin(), buffer2.end()); + } + + EXPECT_EQ(2 * sizeof(uint32_t), buffer.size()); + + auto b = buffer.begin(); + ASSERT_NE(b, buffer.end()); + ASSERT_EQ(sizeof(uint32_t), b->size); + ASSERT_EQ(33u, *reinterpret_cast<uint32_t*>(b->buffer.get())); + ++b; + + ASSERT_NE(b, buffer.end()); + ASSERT_EQ(sizeof(uint32_t), b->size); + ASSERT_EQ(44u, *reinterpret_cast<uint32_t*>(b->buffer.get())); + ++b; + + ASSERT_EQ(b, buffer.end()); +} + +TEST(BigBufferTest, PadAndAlignProperly) { + BigBuffer buffer(16); + + ASSERT_THAT(buffer.NextBlock<char>(2), NotNull()); + ASSERT_EQ(2u, buffer.size()); + buffer.Pad(2); + ASSERT_EQ(4u, buffer.size()); + buffer.Align4(); + ASSERT_EQ(4u, buffer.size()); + buffer.Pad(2); + ASSERT_EQ(6u, buffer.size()); + buffer.Align4(); + ASSERT_EQ(8u, buffer.size()); +} + +} // namespace android diff --git a/libs/androidfw/tests/ResourceTimer_test.cpp b/libs/androidfw/tests/ResourceTimer_test.cpp new file mode 100644 index 000000000000..4a1e9735de7a --- /dev/null +++ b/libs/androidfw/tests/ResourceTimer_test.cpp @@ -0,0 +1,245 @@ +/* + * 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 <android-base/file.h> +#include <android-base/test_utils.h> +#include <androidfw/Util.h> + +#include "TestHelpers.h" + +#include <androidfw/ResourceTimer.h> + +namespace android { + +namespace { + +// Create a reading in us. This is a convenience function to avoid multiplying by 1000 +// everywhere. +unsigned int US(int us) { + return us * 1000; +} + +} + +TEST(ResourceTimerTest, TimerBasic) { + ResourceTimer::Timer timer; + ASSERT_THAT(timer.count, 0); + ASSERT_THAT(timer.total, 0); + + for (int i = 1; i <= 100; i++) { + timer.record(US(i)); + } + ASSERT_THAT(timer.count, 100); + ASSERT_THAT(timer.total, US((101 * 100)/2)); + ASSERT_THAT(timer.mintime, US(1)); + ASSERT_THAT(timer.maxtime, US(100)); + ASSERT_THAT(timer.pvalues.p50.floor, 0); + ASSERT_THAT(timer.pvalues.p50.nominal, 0); + ASSERT_THAT(timer.largest[0], US(100)); + ASSERT_THAT(timer.largest[1], US(99)); + ASSERT_THAT(timer.largest[2], US(98)); + ASSERT_THAT(timer.largest[3], US(97)); + ASSERT_THAT(timer.largest[4], US(96)); + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(49)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(50)); + ASSERT_THAT(timer.pvalues.p90.floor, US(89)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(90)); + ASSERT_THAT(timer.pvalues.p95.floor, US(94)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(95)); + ASSERT_THAT(timer.pvalues.p99.floor, US(98)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(99)); + + // Test reset functionality. All values should be zero after the reset. Computing pvalues + // after the result should also yield zeros. + timer.reset(); + ASSERT_THAT(timer.count, 0); + ASSERT_THAT(timer.total, 0); + ASSERT_THAT(timer.mintime, US(0)); + ASSERT_THAT(timer.maxtime, US(0)); + ASSERT_THAT(timer.pvalues.p50.floor, US(0)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(0)); + ASSERT_THAT(timer.largest[0], US(0)); + ASSERT_THAT(timer.largest[1], US(0)); + ASSERT_THAT(timer.largest[2], US(0)); + ASSERT_THAT(timer.largest[3], US(0)); + ASSERT_THAT(timer.largest[4], US(0)); + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(0)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(0)); + ASSERT_THAT(timer.pvalues.p90.floor, US(0)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(0)); + ASSERT_THAT(timer.pvalues.p95.floor, US(0)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(0)); + ASSERT_THAT(timer.pvalues.p99.floor, US(0)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(0)); + + // Test again, adding elements in reverse. + for (int i = 100; i >= 1; i--) { + timer.record(US(i)); + } + ASSERT_THAT(timer.count, 100); + ASSERT_THAT(timer.total, US((101 * 100)/2)); + ASSERT_THAT(timer.mintime, US(1)); + ASSERT_THAT(timer.maxtime, US(100)); + ASSERT_THAT(timer.pvalues.p50.floor, 0); + ASSERT_THAT(timer.pvalues.p50.nominal, 0); + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(49)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(50)); + ASSERT_THAT(timer.pvalues.p90.floor, US(89)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(90)); + ASSERT_THAT(timer.pvalues.p95.floor, US(94)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(95)); + ASSERT_THAT(timer.pvalues.p99.floor, US(98)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(99)); + ASSERT_THAT(timer.largest[0], US(100)); + ASSERT_THAT(timer.largest[1], US(99)); + ASSERT_THAT(timer.largest[2], US(98)); + ASSERT_THAT(timer.largest[3], US(97)); + ASSERT_THAT(timer.largest[4], US(96)); +} + +TEST(ResourceTimerTest, TimerLimit) { + ResourceTimer::Timer timer; + + // Event truncation means that a time of 1050us will be stored in the 1000us + // bucket. Since there is a single event, all p-values lie in the same range. + timer.record(US(1050)); + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(900)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(1000)); + ASSERT_THAT(timer.pvalues.p90.floor, US(900)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(1000)); + ASSERT_THAT(timer.pvalues.p95.floor, US(900)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(1000)); + ASSERT_THAT(timer.pvalues.p99.floor, US(900)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(1000)); +} + +TEST(ResourceTimerTest, TimerCopy) { + ResourceTimer::Timer source; + for (int i = 1; i <= 100; i++) { + source.record(US(i)); + } + ResourceTimer::Timer timer; + ResourceTimer::Timer::copy(timer, source, true); + ASSERT_THAT(source.count, 0); + ASSERT_THAT(source.total, 0); + // compute() is not normally be called on a reset timer, but it should work and it should return + // all zeros. + source.compute(); + ASSERT_THAT(source.pvalues.p50.floor, US(0)); + ASSERT_THAT(source.pvalues.p50.nominal, US(0)); + ASSERT_THAT(source.pvalues.p90.floor, US(0)); + ASSERT_THAT(source.pvalues.p90.nominal, US(0)); + ASSERT_THAT(source.pvalues.p95.floor, US(0)); + ASSERT_THAT(source.pvalues.p95.nominal, US(0)); + ASSERT_THAT(source.pvalues.p99.floor, US(0)); + ASSERT_THAT(source.pvalues.p99.nominal, US(0)); + ASSERT_THAT(source.largest[0], US(0)); + ASSERT_THAT(source.largest[1], US(0)); + ASSERT_THAT(source.largest[2], US(0)); + ASSERT_THAT(source.largest[3], US(0)); + ASSERT_THAT(source.largest[4], US(0)); + + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(49)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(50)); + ASSERT_THAT(timer.pvalues.p90.floor, US(89)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(90)); + ASSERT_THAT(timer.pvalues.p95.floor, US(94)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(95)); + ASSERT_THAT(timer.pvalues.p99.floor, US(98)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(99)); + ASSERT_THAT(timer.largest[0], US(100)); + ASSERT_THAT(timer.largest[1], US(99)); + ASSERT_THAT(timer.largest[2], US(98)); + ASSERT_THAT(timer.largest[3], US(97)); + ASSERT_THAT(timer.largest[4], US(96)); + + // Call compute a second time. The values must be the same. + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(49)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(50)); + ASSERT_THAT(timer.pvalues.p90.floor, US(89)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(90)); + ASSERT_THAT(timer.pvalues.p95.floor, US(94)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(95)); + ASSERT_THAT(timer.pvalues.p99.floor, US(98)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(99)); + ASSERT_THAT(timer.largest[0], US(100)); + ASSERT_THAT(timer.largest[1], US(99)); + ASSERT_THAT(timer.largest[2], US(98)); + ASSERT_THAT(timer.largest[3], US(97)); + ASSERT_THAT(timer.largest[4], US(96)); + + // Modify the source. If timer and source share histogram arrays, this will introduce an + // error. + for (int i = 1; i <= 100; i++) { + source.record(US(i)); + } + // Call compute a third time. The values must be the same. + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(49)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(50)); + ASSERT_THAT(timer.pvalues.p90.floor, US(89)); + ASSERT_THAT(timer.pvalues.p90.nominal, US(90)); + ASSERT_THAT(timer.pvalues.p95.floor, US(94)); + ASSERT_THAT(timer.pvalues.p95.nominal, US(95)); + ASSERT_THAT(timer.pvalues.p99.floor, US(98)); + ASSERT_THAT(timer.pvalues.p99.nominal, US(99)); + ASSERT_THAT(timer.largest[0], US(100)); + ASSERT_THAT(timer.largest[1], US(99)); + ASSERT_THAT(timer.largest[2], US(98)); + ASSERT_THAT(timer.largest[3], US(97)); + ASSERT_THAT(timer.largest[4], US(96)); +} + +// Verify that if too many oversize entries are reported, the percentile values cannot be computed +// and are set to zero. +TEST(ResourceTimerTest, TimerOversize) { + static const int oversize = US(2 * 1000 * 1000); + + ResourceTimer::Timer timer; + for (int i = 1; i <= 100; i++) { + timer.record(US(i)); + } + + // Insert enough oversize values to invalidate the p90, p95, and p99 percentiles. The p50 is + // still computable. + for (int i = 1; i <= 50; i++) { + timer.record(oversize); + } + ASSERT_THAT(timer.largest[0], oversize); + ASSERT_THAT(timer.largest[1], oversize); + ASSERT_THAT(timer.largest[2], oversize); + ASSERT_THAT(timer.largest[3], oversize); + ASSERT_THAT(timer.largest[4], oversize); + timer.compute(); + ASSERT_THAT(timer.pvalues.p50.floor, US(74)); + ASSERT_THAT(timer.pvalues.p50.nominal, US(75)); + ASSERT_THAT(timer.pvalues.p90.floor, 0); + ASSERT_THAT(timer.pvalues.p90.nominal, 0); + ASSERT_THAT(timer.pvalues.p95.floor, 0); + ASSERT_THAT(timer.pvalues.p95.nominal, 0); + ASSERT_THAT(timer.pvalues.p99.floor, 0); + ASSERT_THAT(timer.pvalues.p99.nominal, 0); +} + + +} // namespace android diff --git a/libs/androidfw/tests/StringPool_test.cpp b/libs/androidfw/tests/StringPool_test.cpp new file mode 100644 index 000000000000..047d45785409 --- /dev/null +++ b/libs/androidfw/tests/StringPool_test.cpp @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "androidfw/StringPool.h" + +#include <string> + +#include "androidfw/IDiagnostics.h" +#include "androidfw/StringPiece.h" +#include "androidfw/Util.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using ::android::StringPiece; +using ::android::StringPiece16; +using ::testing::Eq; +using ::testing::Ne; +using ::testing::NotNull; +using ::testing::Pointee; + +namespace android { + +TEST(StringPoolTest, InsertOneString) { + StringPool pool; + + StringPool::Ref ref = pool.MakeRef("wut"); + EXPECT_THAT(*ref, Eq("wut")); +} + +TEST(StringPoolTest, InsertTwoUniqueStrings) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("wut"); + StringPool::Ref ref_b = pool.MakeRef("hey"); + + EXPECT_THAT(*ref_a, Eq("wut")); + EXPECT_THAT(*ref_b, Eq("hey")); +} + +TEST(StringPoolTest, DoNotInsertNewDuplicateString) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("wut"); + StringPool::Ref ref_b = pool.MakeRef("wut"); + + EXPECT_THAT(*ref_a, Eq("wut")); + EXPECT_THAT(*ref_b, Eq("wut")); + EXPECT_THAT(pool.size(), Eq(1u)); +} + +TEST(StringPoolTest, DoNotDedupeSameStringDifferentPriority) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("wut", StringPool::Context(0x81010001)); + StringPool::Ref ref_b = pool.MakeRef("wut", StringPool::Context(0x81010002)); + + EXPECT_THAT(*ref_a, Eq("wut")); + EXPECT_THAT(*ref_b, Eq("wut")); + EXPECT_THAT(pool.size(), Eq(2u)); +} + +TEST(StringPoolTest, MaintainInsertionOrderIndex) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("z"); + StringPool::Ref ref_b = pool.MakeRef("a"); + StringPool::Ref ref_c = pool.MakeRef("m"); + + EXPECT_THAT(ref_a.index(), Eq(0u)); + EXPECT_THAT(ref_b.index(), Eq(1u)); + EXPECT_THAT(ref_c.index(), Eq(2u)); +} + +TEST(StringPoolTest, PruneStringsWithNoReferences) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("foo"); + + { + StringPool::Ref ref_b = pool.MakeRef("wut"); + EXPECT_THAT(*ref_b, Eq("wut")); + EXPECT_THAT(pool.size(), Eq(2u)); + pool.Prune(); + EXPECT_THAT(pool.size(), Eq(2u)); + } + EXPECT_THAT(pool.size(), Eq(2u)); + + { + StringPool::Ref ref_c = pool.MakeRef("bar"); + EXPECT_THAT(pool.size(), Eq(3u)); + + pool.Prune(); + EXPECT_THAT(pool.size(), Eq(2u)); + } + EXPECT_THAT(pool.size(), Eq(2u)); + + pool.Prune(); + EXPECT_THAT(pool.size(), Eq(1u)); +} + +TEST(StringPoolTest, SortAndMaintainIndexesInStringReferences) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("z"); + StringPool::Ref ref_b = pool.MakeRef("a"); + StringPool::Ref ref_c = pool.MakeRef("m"); + + EXPECT_THAT(*ref_a, Eq("z")); + EXPECT_THAT(ref_a.index(), Eq(0u)); + + EXPECT_THAT(*ref_b, Eq("a")); + EXPECT_THAT(ref_b.index(), Eq(1u)); + + EXPECT_THAT(*ref_c, Eq("m")); + EXPECT_THAT(ref_c.index(), Eq(2u)); + + pool.Sort(); + + EXPECT_THAT(*ref_a, Eq("z")); + EXPECT_THAT(ref_a.index(), Eq(2u)); + + EXPECT_THAT(*ref_b, Eq("a")); + EXPECT_THAT(ref_b.index(), Eq(0u)); + + EXPECT_THAT(*ref_c, Eq("m")); + EXPECT_THAT(ref_c.index(), Eq(1u)); +} + +TEST(StringPoolTest, SortAndStillDedupe) { + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("z"); + StringPool::Ref ref_b = pool.MakeRef("a"); + StringPool::Ref ref_c = pool.MakeRef("m"); + + pool.Sort(); + + StringPool::Ref ref_d = pool.MakeRef("z"); + StringPool::Ref ref_e = pool.MakeRef("a"); + StringPool::Ref ref_f = pool.MakeRef("m"); + + EXPECT_THAT(ref_d.index(), Eq(ref_a.index())); + EXPECT_THAT(ref_e.index(), Eq(ref_b.index())); + EXPECT_THAT(ref_f.index(), Eq(ref_c.index())); +} + +TEST(StringPoolTest, AddStyles) { + StringPool pool; + + StringPool::StyleRef ref = pool.MakeRef(StyleString{{"android"}, {Span{{"b"}, 2, 6}}}); + EXPECT_THAT(ref.index(), Eq(0u)); + EXPECT_THAT(ref->value, Eq("android")); + ASSERT_THAT(ref->spans.size(), Eq(1u)); + + const StringPool::Span& span = ref->spans.front(); + EXPECT_THAT(*span.name, Eq("b")); + EXPECT_THAT(span.first_char, Eq(2u)); + EXPECT_THAT(span.last_char, Eq(6u)); +} + +TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) { + StringPool pool; + + StringPool::Ref ref = pool.MakeRef("android"); + + StyleString str{{"android"}, {}}; + StringPool::StyleRef style_ref = pool.MakeRef(StyleString{{"android"}, {}}); + + EXPECT_THAT(ref.index(), Ne(style_ref.index())); +} + +TEST(StringPoolTest, StylesAndStringsAreSeparateAfterSorting) { + StringPool pool; + + StringPool::StyleRef ref_a = pool.MakeRef(StyleString{{"beta"}, {}}); + StringPool::Ref ref_b = pool.MakeRef("alpha"); + StringPool::StyleRef ref_c = pool.MakeRef(StyleString{{"alpha"}, {}}); + + EXPECT_THAT(ref_b.index(), Ne(ref_c.index())); + + pool.Sort(); + + EXPECT_THAT(ref_c.index(), Eq(0u)); + EXPECT_THAT(ref_a.index(), Eq(1u)); + EXPECT_THAT(ref_b.index(), Eq(2u)); +} + +TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) { + using namespace android; // For NO_ERROR on Windows. + NoOpDiagnostics diag; + + StringPool pool; + BigBuffer buffer(1024); + StringPool::FlattenUtf8(&buffer, pool, &diag); + + std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer); + ResStringPool test; + ASSERT_THAT(test.setTo(data.get(), buffer.size()), Eq(NO_ERROR)); +} + +TEST(StringPoolTest, FlattenOddCharactersUtf16) { + using namespace android; // For NO_ERROR on Windows. + NoOpDiagnostics diag; + + StringPool pool; + pool.MakeRef("\u093f"); + BigBuffer buffer(1024); + StringPool::FlattenUtf16(&buffer, pool, &diag); + + std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer); + ResStringPool test; + ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR); + auto str = test.stringAt(0); + ASSERT_TRUE(str.has_value()); + EXPECT_THAT(str->size(), Eq(1u)); + EXPECT_THAT(str->data(), Pointee(Eq(u'\u093f'))); + EXPECT_THAT(str->data()[1], Eq(0u)); +} + +constexpr const char* sLongString = + "バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑" + "え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限" + "します。メール、SMSや、同期を使 " + "用するその他のアプリは、起動しても更新されないことがあります。バッテリーセ" + "ーバーは端末の充電中は自動的にOFFになります。"; + +TEST(StringPoolTest, Flatten) { + using namespace android; // For NO_ERROR on Windows. + NoOpDiagnostics diag; + + StringPool pool; + + StringPool::Ref ref_a = pool.MakeRef("hello"); + StringPool::Ref ref_b = pool.MakeRef("goodbye"); + StringPool::Ref ref_c = pool.MakeRef(sLongString); + StringPool::Ref ref_d = pool.MakeRef(""); + StringPool::StyleRef ref_e = + pool.MakeRef(StyleString{{"style"}, {Span{{"b"}, 0, 1}, Span{{"i"}, 2, 3}}}); + + // Styles are always first. + EXPECT_THAT(ref_e.index(), Eq(0u)); + + EXPECT_THAT(ref_a.index(), Eq(1u)); + EXPECT_THAT(ref_b.index(), Eq(2u)); + EXPECT_THAT(ref_c.index(), Eq(3u)); + EXPECT_THAT(ref_d.index(), Eq(4u)); + + BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)}; + StringPool::FlattenUtf8(&buffers[0], pool, &diag); + StringPool::FlattenUtf16(&buffers[1], pool, &diag); + + // Test both UTF-8 and UTF-16 buffers. + for (const BigBuffer& buffer : buffers) { + std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer); + + ResStringPool test; + ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR); + + EXPECT_THAT(android::util::GetString(test, 1), Eq("hello")); + EXPECT_THAT(android::util::GetString16(test, 1), Eq(u"hello")); + + EXPECT_THAT(android::util::GetString(test, 2), Eq("goodbye")); + EXPECT_THAT(android::util::GetString16(test, 2), Eq(u"goodbye")); + + EXPECT_THAT(android::util::GetString(test, 3), Eq(sLongString)); + EXPECT_THAT(android::util::GetString16(test, 3), Eq(util::Utf8ToUtf16(sLongString))); + + EXPECT_TRUE(test.stringAt(4).has_value() || test.string8At(4).has_value()); + + EXPECT_THAT(android::util::GetString(test, 0), Eq("style")); + EXPECT_THAT(android::util::GetString16(test, 0), Eq(u"style")); + + auto span_result = test.styleAt(0); + ASSERT_TRUE(span_result.has_value()); + + const ResStringPool_span* span = span_result->unsafe_ptr(); + EXPECT_THAT(android::util::GetString(test, span->name.index), Eq("b")); + EXPECT_THAT(android::util::GetString16(test, span->name.index), Eq(u"b")); + EXPECT_THAT(span->firstChar, Eq(0u)); + EXPECT_THAT(span->lastChar, Eq(1u)); + span++; + + ASSERT_THAT(span->name.index, Ne(ResStringPool_span::END)); + EXPECT_THAT(android::util::GetString(test, span->name.index), Eq("i")); + EXPECT_THAT(android::util::GetString16(test, span->name.index), Eq(u"i")); + EXPECT_THAT(span->firstChar, Eq(2u)); + EXPECT_THAT(span->lastChar, Eq(3u)); + span++; + + EXPECT_THAT(span->name.index, Eq(ResStringPool_span::END)); + } +} + +TEST(StringPoolTest, ModifiedUTF8) { + using namespace android; // For NO_ERROR on Windows. + NoOpDiagnostics diag; + StringPool pool; + StringPool::Ref ref_a = pool.MakeRef("\xF0\x90\x90\x80"); // 𐐀 (U+10400) + StringPool::Ref ref_b = pool.MakeRef("foo \xF0\x90\x90\xB7 bar"); // 𐐷 (U+10437) + StringPool::Ref ref_c = pool.MakeRef("\xF0\x90\x90\x80\xF0\x90\x90\xB7"); + + BigBuffer buffer(1024); + StringPool::FlattenUtf8(&buffer, pool, &diag); + std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer); + + // Check that the codepoints are encoded using two three-byte surrogate pairs + ResStringPool test; + ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR); + auto str = test.string8At(0); + ASSERT_TRUE(str.has_value()); + EXPECT_THAT(str->to_string(), Eq("\xED\xA0\x81\xED\xB0\x80")); + + str = test.string8At(1); + ASSERT_TRUE(str.has_value()); + EXPECT_THAT(str->to_string(), Eq("foo \xED\xA0\x81\xED\xB0\xB7 bar")); + + str = test.string8At(2); + ASSERT_TRUE(str.has_value()); + EXPECT_THAT(str->to_string(), Eq("\xED\xA0\x81\xED\xB0\x80\xED\xA0\x81\xED\xB0\xB7")); + + // Check that retrieving the strings returns the original UTF-8 character bytes + EXPECT_THAT(android::util::GetString(test, 0), Eq("\xF0\x90\x90\x80")); + EXPECT_THAT(android::util::GetString(test, 1), Eq("foo \xF0\x90\x90\xB7 bar")); + EXPECT_THAT(android::util::GetString(test, 2), Eq("\xF0\x90\x90\x80\xF0\x90\x90\xB7")); +} + +TEST(StringPoolTest, MaxEncodingLength) { + NoOpDiagnostics diag; + using namespace android; // For NO_ERROR on Windows. + ResStringPool test; + + StringPool pool; + pool.MakeRef("aaaaaaaaaa"); + BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)}; + + // Make sure a UTF-8 string under the maximum length does not produce an error + EXPECT_THAT(StringPool::FlattenUtf8(&buffers[0], pool, &diag), Eq(true)); + std::unique_ptr<uint8_t[]> data = android::util::Copy(buffers[0]); + test.setTo(data.get(), buffers[0].size()); + EXPECT_THAT(android::util::GetString(test, 0), Eq("aaaaaaaaaa")); + + // Make sure a UTF-16 string under the maximum length does not produce an error + EXPECT_THAT(StringPool::FlattenUtf16(&buffers[1], pool, &diag), Eq(true)); + data = android::util::Copy(buffers[1]); + test.setTo(data.get(), buffers[1].size()); + EXPECT_THAT(android::util::GetString16(test, 0), Eq(u"aaaaaaaaaa")); + + StringPool pool2; + std::string longStr(50000, 'a'); + pool2.MakeRef("this fits1"); + pool2.MakeRef(longStr); + pool2.MakeRef("this fits2"); + BigBuffer buffers2[2] = {BigBuffer(1024), BigBuffer(1024)}; + + // Make sure a string that exceeds the maximum length of UTF-8 produces an + // error and writes a shorter error string instead + EXPECT_THAT(StringPool::FlattenUtf8(&buffers2[0], pool2, &diag), Eq(false)); + data = android::util::Copy(buffers2[0]); + test.setTo(data.get(), buffers2[0].size()); + EXPECT_THAT(android::util::GetString(test, 0), "this fits1"); + EXPECT_THAT(android::util::GetString(test, 1), "STRING_TOO_LARGE"); + EXPECT_THAT(android::util::GetString(test, 2), "this fits2"); + + // Make sure a string that a string that exceeds the maximum length of UTF-8 + // but not UTF-16 does not error for UTF-16 + StringPool pool3; + std::u16string longStr16(50000, 'a'); + pool3.MakeRef(longStr); + EXPECT_THAT(StringPool::FlattenUtf16(&buffers2[1], pool3, &diag), Eq(true)); + data = android::util::Copy(buffers2[1]); + test.setTo(data.get(), buffers2[1].size()); + EXPECT_THAT(android::util::GetString16(test, 0), Eq(longStr16)); +} + +} // namespace android diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap Binary files differindex 88eadccb38cf..8e847e81aa31 100644 --- a/libs/androidfw/tests/data/overlay/overlay.idmap +++ b/libs/androidfw/tests/data/overlay/overlay.idmap diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index ad9aa6cdd3d9..b11e542472da 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -93,6 +93,10 @@ cc_defaults { cc_defaults { name: "hwui_static_deps", + defaults: [ + "android.hardware.graphics.common-ndk_shared", + "android.hardware.graphics.composer3-ndk_shared", + ], shared_libs: [ "libbase", "libharfbuzz_ng", @@ -106,9 +110,7 @@ cc_defaults { target: { android: { shared_libs: [ - "android.hardware.graphics.common-V3-ndk", "android.hardware.graphics.common@1.2", - "android.hardware.graphics.composer3-V1-ndk", "liblog", "libcutils", "libutils", @@ -345,6 +347,7 @@ cc_defaults { "jni/PaintFilter.cpp", "jni/Path.cpp", "jni/PathEffect.cpp", + "jni/PathIterator.cpp", "jni/PathMeasure.cpp", "jni/Picture.cpp", "jni/Region.cpp", diff --git a/libs/hwui/CopyRequest.h b/libs/hwui/CopyRequest.h new file mode 100644 index 000000000000..5fbd5f900716 --- /dev/null +++ b/libs/hwui/CopyRequest.h @@ -0,0 +1,42 @@ +/* + * 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 "Rect.h" +#include "hwui/Bitmap.h" + +namespace android::uirenderer { + +// Keep in sync with PixelCopy.java codes +enum class CopyResult { + Success = 0, + UnknownError = 1, + Timeout = 2, + SourceEmpty = 3, + SourceInvalid = 4, + DestinationInvalid = 5, +}; + +struct CopyRequest { + Rect srcRect; + CopyRequest(Rect srcRect) : srcRect(srcRect) {} + virtual ~CopyRequest() {} + virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) = 0; + virtual void onCopyFinished(CopyResult result) = 0; +}; + +} // namespace android::uirenderer diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h index d5fee3f667a9..2e6e36a9ff22 100644 --- a/libs/hwui/DeviceInfo.h +++ b/libs/hwui/DeviceInfo.h @@ -16,7 +16,9 @@ #ifndef DEVICEINFO_H #define DEVICEINFO_H +#include <SkColorSpace.h> #include <SkImageInfo.h> +#include <SkRefCnt.h> #include <android/data_space.h> #include <mutex> diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp index c24cabb287de..7291cab364e2 100644 --- a/libs/hwui/HardwareBitmapUploader.cpp +++ b/libs/hwui/HardwareBitmapUploader.cpp @@ -22,8 +22,11 @@ #include <GLES2/gl2ext.h> #include <GLES3/gl3.h> #include <GrDirectContext.h> +#include <SkBitmap.h> #include <SkCanvas.h> #include <SkImage.h> +#include <SkImageInfo.h> +#include <SkRefCnt.h> #include <gui/TraceUtils.h> #include <utils/GLUtils.h> #include <utils/NdkUtils.h> diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h index 81057a24c29c..00ee99648889 100644 --- a/libs/hwui/HardwareBitmapUploader.h +++ b/libs/hwui/HardwareBitmapUploader.h @@ -17,6 +17,9 @@ #pragma once #include <hwui/Bitmap.h> +#include <SkRefCnt.h> + +class SkBitmap; namespace android::uirenderer { diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index a3ba88e4ee8a..02c2e67a319b 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -26,6 +26,18 @@ #include "pipeline/skia/LayerDrawable.h" #include "renderthread/EglManager.h" #include "renderthread/VulkanManager.h" +#include <SkBitmap.h> +#include <SkBlendMode.h> +#include <SkCanvas.h> +#include <SkColorSpace.h> +#include <SkImage.h> +#include <SkImageInfo.h> +#include <SkMatrix.h> +#include <SkPaint.h> +#include <SkRect.h> +#include <SkRefCnt.h> +#include <SkSamplingOptions.h> +#include <SkSurface.h> #include "utils/Color.h" #include "utils/MathUtils.h" #include "utils/NdkUtils.h" @@ -37,8 +49,7 @@ namespace uirenderer { #define ARECT_ARGS(r) float((r).left), float((r).top), float((r).right), float((r).bottom) -CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRect, - SkBitmap* bitmap) { +void Readback::copySurfaceInto(ANativeWindow* window, const std::shared_ptr<CopyRequest>& request) { ATRACE_CALL(); // Setup the source AHardwareBuffer* rawSourceBuffer; @@ -51,30 +62,33 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec // Really this shouldn't ever happen, but better safe than sorry. if (err == UNKNOWN_TRANSACTION) { ALOGW("Readback failed to ANativeWindow_getLastQueuedBuffer2 - who are we talking to?"); - return copySurfaceIntoLegacy(window, inSrcRect, bitmap); + return request->onCopyFinished(CopyResult::SourceInvalid); } ALOGV("Using new path, cropRect=" RECT_STRING ", transform=%x", ARECT_ARGS(cropRect), windowTransform); if (err != NO_ERROR) { ALOGW("Failed to get last queued buffer, error = %d", err); - return CopyResult::UnknownError; + return request->onCopyFinished(CopyResult::SourceInvalid); } if (rawSourceBuffer == nullptr) { ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); - return CopyResult::SourceEmpty; + return request->onCopyFinished(CopyResult::SourceEmpty); } UniqueAHardwareBuffer sourceBuffer{rawSourceBuffer}; AHardwareBuffer_Desc description; AHardwareBuffer_describe(sourceBuffer.get(), &description); if (description.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) { ALOGW("Surface is protected, unable to copy from it"); - return CopyResult::SourceInvalid; + return request->onCopyFinished(CopyResult::SourceInvalid); } - if (sourceFence != -1 && sync_wait(sourceFence.get(), 500 /* ms */) != NO_ERROR) { - ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); - return CopyResult::Timeout; + { + ATRACE_NAME("sync_wait"); + if (sourceFence != -1 && sync_wait(sourceFence.get(), 500 /* ms */) != NO_ERROR) { + ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); + return request->onCopyFinished(CopyResult::Timeout); + } } sk_sp<SkColorSpace> colorSpace = DataSpaceToColorSpace( @@ -83,12 +97,12 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec SkImage::MakeFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, colorSpace); if (!image.get()) { - return CopyResult::UnknownError; + return request->onCopyFinished(CopyResult::UnknownError); } sk_sp<GrDirectContext> grContext = mRenderThread.requireGrContext(); - SkRect srcRect = inSrcRect.toSkRect(); + SkRect srcRect = request->srcRect.toSkRect(); SkRect imageSrcRect = SkRect::MakeIWH(description.width, description.height); SkISize imageWH = SkISize::Make(description.width, description.height); @@ -136,10 +150,12 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec ALOGV("intersecting " RECT_STRING " with " RECT_STRING, SK_RECT_ARGS(srcRect), SK_RECT_ARGS(textureRect)); if (!srcRect.intersect(textureRect)) { - return CopyResult::UnknownError; + return request->onCopyFinished(CopyResult::UnknownError); } } + SkBitmap skBitmap = request->getDestinationBitmap(srcRect.width(), srcRect.height()); + SkBitmap* bitmap = &skBitmap; sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes, bitmap->info(), 0, kTopLeft_GrSurfaceOrigin, nullptr); @@ -152,7 +168,7 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr); if (!tmpSurface.get()) { ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap"); - return CopyResult::UnknownError; + return request->onCopyFinished(CopyResult::UnknownError); } } @@ -223,52 +239,13 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec !tmpBitmap.tryAllocPixels(tmpInfo) || !tmpSurface->readPixels(tmpBitmap, 0, 0) || !tmpBitmap.readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) { ALOGW("Unable to convert content into the provided bitmap"); - return CopyResult::UnknownError; + return request->onCopyFinished(CopyResult::UnknownError); } } bitmap->notifyPixelsChanged(); - return CopyResult::Success; -} - -CopyResult Readback::copySurfaceIntoLegacy(ANativeWindow* window, const Rect& srcRect, - SkBitmap* bitmap) { - // Setup the source - AHardwareBuffer* rawSourceBuffer; - int rawSourceFence; - Matrix4 texTransform; - status_t err = ANativeWindow_getLastQueuedBuffer(window, &rawSourceBuffer, &rawSourceFence, - texTransform.data); - base::unique_fd sourceFence(rawSourceFence); - texTransform.invalidateType(); - if (err != NO_ERROR) { - ALOGW("Failed to get last queued buffer, error = %d", err); - return CopyResult::UnknownError; - } - if (rawSourceBuffer == nullptr) { - ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); - return CopyResult::SourceEmpty; - } - - UniqueAHardwareBuffer sourceBuffer{rawSourceBuffer}; - AHardwareBuffer_Desc description; - AHardwareBuffer_describe(sourceBuffer.get(), &description); - if (description.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) { - ALOGW("Surface is protected, unable to copy from it"); - return CopyResult::SourceInvalid; - } - - if (sourceFence != -1 && sync_wait(sourceFence.get(), 500 /* ms */) != NO_ERROR) { - ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); - return CopyResult::Timeout; - } - - sk_sp<SkColorSpace> colorSpace = DataSpaceToColorSpace( - static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(window))); - sk_sp<SkImage> image = - SkImage::MakeFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, colorSpace); - return copyImageInto(image, srcRect, bitmap); + return request->onCopyFinished(CopyResult::Success); } CopyResult Readback::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { @@ -306,14 +283,14 @@ CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, const Rect& srcRect, SkBitmap* bitmap) { ATRACE_CALL(); + if (!image.get()) { + return CopyResult::UnknownError; + } if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { mRenderThread.requireGlContext(); } else { mRenderThread.requireVkContext(); } - if (!image.get()) { - return CopyResult::UnknownError; - } int imgWidth = image->width(); int imgHeight = image->height(); sk_sp<GrDirectContext> grContext = sk_ref_sp(mRenderThread.getGrContext()); diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h index d0d748ff5c16..a092d472abf0 100644 --- a/libs/hwui/Readback.h +++ b/libs/hwui/Readback.h @@ -16,11 +16,16 @@ #pragma once +#include <SkRefCnt.h> + +#include "CopyRequest.h" #include "Matrix.h" #include "Rect.h" #include "renderthread/RenderThread.h" -#include <SkBitmap.h> +class SkBitmap; +class SkImage; +struct SkRect; namespace android { class Bitmap; @@ -31,23 +36,13 @@ namespace uirenderer { class DeferredLayerUpdater; class Layer; -// Keep in sync with PixelCopy.java codes -enum class CopyResult { - Success = 0, - UnknownError = 1, - Timeout = 2, - SourceEmpty = 3, - SourceInvalid = 4, - DestinationInvalid = 5, -}; - class Readback { public: explicit Readback(renderthread::RenderThread& thread) : mRenderThread(thread) {} /** * Copies the surface's most recently queued buffer into the provided bitmap. */ - CopyResult copySurfaceInto(ANativeWindow* window, const Rect& srcRect, SkBitmap* bitmap); + void copySurfaceInto(ANativeWindow* window, const std::shared_ptr<CopyRequest>& request); CopyResult copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap); CopyResult copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap); @@ -55,7 +50,6 @@ public: CopyResult copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); private: - CopyResult copySurfaceIntoLegacy(ANativeWindow* window, const Rect& srcRect, SkBitmap* bitmap); CopyResult copyImageInto(const sk_sp<SkImage>& image, const Rect& srcRect, SkBitmap* bitmap); bool copyLayerInto(Layer* layer, const SkRect* srcRect, const SkRect* dstRect, diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index a285462eef74..f5ebfd5d9e23 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -29,10 +29,14 @@ #include "SkDrawShadowInfo.h" #include "SkImage.h" #include "SkImageFilter.h" +#include "SkImageInfo.h" #include "SkLatticeIter.h" #include "SkMath.h" +#include "SkPaint.h" #include "SkPicture.h" +#include "SkRRect.h" #include "SkRSXform.h" +#include "SkRect.h" #include "SkRegion.h" #include "SkTextBlob.h" #include "SkVertices.h" diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index 212b4e72dcb2..35bec9335d7c 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -34,6 +34,8 @@ #include <SkRuntimeEffect.h> #include <vector> +class SkRRect; + namespace android { namespace uirenderer { diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index da0476259b97..bdc48e91f6cb 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -16,7 +16,6 @@ #pragma once -#include <SkCamera.h> #include <SkMatrix.h> #include <utils/LinearAllocator.h> diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index f9b3a8c12b2e..473afbd2aa2f 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -18,6 +18,7 @@ #include "CanvasProperty.h" #include "NinePatchUtils.h" +#include "SkBlendMode.h" #include "VectorDrawable.h" #include "hwui/Bitmap.h" #include "hwui/MinikinUtils.h" @@ -27,6 +28,7 @@ #include <SkAndroidFrameworkUtils.h> #include <SkAnimatedImage.h> +#include <SkBitmap.h> #include <SkCanvasPriv.h> #include <SkCanvasStateUtils.h> #include <SkColorFilter.h> @@ -36,8 +38,13 @@ #include <SkGraphics.h> #include <SkImage.h> #include <SkImagePriv.h> +#include <SkMatrix.h> +#include <SkPaint.h> #include <SkPicture.h> #include <SkRSXform.h> +#include <SkRRect.h> +#include <SkRect.h> +#include <SkRefCnt.h> #include <SkShader.h> #include <SkTemplates.h> #include <SkTextBlob.h> @@ -245,10 +252,11 @@ const SkiaCanvas::SaveRec* SkiaCanvas::currentSaveRec() const { return (rec && rec->saveCount == currentSaveCount) ? rec : nullptr; } -void SkiaCanvas::punchHole(const SkRRect& rect) { +void SkiaCanvas::punchHole(const SkRRect& rect, float alpha) { SkPaint paint = SkPaint(); - paint.setColor(0); - paint.setBlendMode(SkBlendMode::kClear); + paint.setColor(SkColors::kBlack); + paint.setAlphaf(alpha); + paint.setBlendMode(SkBlendMode::kDstOut); mCanvas->drawRRect(rect, paint); } diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index 715007cdcd3b..51007c52260d 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -33,6 +33,8 @@ #include <cassert> #include <optional> +class SkRRect; + namespace android { // Holds an SkCanvas reference plus additional native data. @@ -63,7 +65,7 @@ public: LOG_ALWAYS_FATAL("SkiaCanvas does not support enableZ"); } - virtual void punchHole(const SkRRect& rect) override; + virtual void punchHole(const SkRRect& rect, float alpha) override; virtual void setBitmap(const SkBitmap& bitmap) override; diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp index 983c7766273a..536ff781badc 100644 --- a/libs/hwui/VectorDrawable.cpp +++ b/libs/hwui/VectorDrawable.cpp @@ -21,9 +21,10 @@ #include <utils/Log.h> #include "PathParser.h" -#include "SkColorFilter.h" +#include "SkImage.h" #include "SkImageInfo.h" -#include "SkShader.h" +#include "SkSamplingOptions.h" +#include "SkScalar.h" #include "hwui/Paint.h" #ifdef __ANDROID__ diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h index 30bb04ae8361..c92654c479c1 100644 --- a/libs/hwui/VectorDrawable.h +++ b/libs/hwui/VectorDrawable.h @@ -31,6 +31,7 @@ #include <SkPath.h> #include <SkPathMeasure.h> #include <SkRect.h> +#include <SkRefCnt.h> #include <SkShader.h> #include <SkSurface.h> diff --git a/libs/hwui/apex/LayoutlibLoader.cpp b/libs/hwui/apex/LayoutlibLoader.cpp index 942c0506321c..b7a15633ff6d 100644 --- a/libs/hwui/apex/LayoutlibLoader.cpp +++ b/libs/hwui/apex/LayoutlibLoader.cpp @@ -53,6 +53,7 @@ extern int register_android_graphics_FontFamily(JNIEnv* env); extern int register_android_graphics_Matrix(JNIEnv* env); extern int register_android_graphics_Paint(JNIEnv* env); extern int register_android_graphics_Path(JNIEnv* env); +extern int register_android_graphics_PathIterator(JNIEnv* env); extern int register_android_graphics_PathMeasure(JNIEnv* env); extern int register_android_graphics_Picture(JNIEnv* env); extern int register_android_graphics_Region(JNIEnv* env); @@ -100,6 +101,7 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = { {"android.graphics.Paint", REG_JNI(register_android_graphics_Paint)}, {"android.graphics.Path", REG_JNI(register_android_graphics_Path)}, {"android.graphics.PathEffect", REG_JNI(register_android_graphics_PathEffect)}, + {"android.graphics.PathIterator", REG_JNI(register_android_graphics_PathIterator)}, {"android.graphics.PathMeasure", REG_JNI(register_android_graphics_PathMeasure)}, {"android.graphics.Picture", REG_JNI(register_android_graphics_Picture)}, {"android.graphics.RecordingCanvas", REG_JNI(register_android_view_DisplayListCanvas)}, diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp index bc6bc456ba5a..c442a7b1d17c 100644 --- a/libs/hwui/apex/android_bitmap.cpp +++ b/libs/hwui/apex/android_bitmap.cpp @@ -24,6 +24,11 @@ #include <GraphicsJNI.h> #include <hwui/Bitmap.h> +#include <SkBitmap.h> +#include <SkColorSpace.h> +#include <SkImageInfo.h> +#include <SkRefCnt.h> +#include <SkStream.h> #include <utils/Color.h> using namespace android; diff --git a/libs/hwui/apex/android_canvas.cpp b/libs/hwui/apex/android_canvas.cpp index 2a939efed9bb..905b123076a2 100644 --- a/libs/hwui/apex/android_canvas.cpp +++ b/libs/hwui/apex/android_canvas.cpp @@ -23,7 +23,9 @@ #include <utils/Color.h> #include <SkBitmap.h> +#include <SkColorSpace.h> #include <SkSurface.h> +#include <SkRefCnt.h> using namespace android; diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp index e1f5abd786bf..39725a55b594 100644 --- a/libs/hwui/apex/jni_runtime.cpp +++ b/libs/hwui/apex/jni_runtime.cpp @@ -59,6 +59,7 @@ extern int register_android_graphics_HardwareRendererObserver(JNIEnv* env); extern int register_android_graphics_Matrix(JNIEnv* env); extern int register_android_graphics_Paint(JNIEnv* env); extern int register_android_graphics_Path(JNIEnv* env); +extern int register_android_graphics_PathIterator(JNIEnv* env); extern int register_android_graphics_PathMeasure(JNIEnv* env); extern int register_android_graphics_Picture(JNIEnv*); extern int register_android_graphics_Region(JNIEnv* env); @@ -94,59 +95,60 @@ extern int register_android_view_ThreadedRenderer(JNIEnv* env); }; #endif -static const RegJNIRec gRegJNI[] = { - REG_JNI(register_android_graphics_Canvas), - // This needs to be before register_android_graphics_Graphics, or the latter - // will not be able to find the jmethodID for ColorSpace.get(). - REG_JNI(register_android_graphics_ColorSpace), - REG_JNI(register_android_graphics_Graphics), - REG_JNI(register_android_graphics_Bitmap), - REG_JNI(register_android_graphics_BitmapFactory), - REG_JNI(register_android_graphics_BitmapRegionDecoder), - REG_JNI(register_android_graphics_ByteBufferStreamAdaptor), - REG_JNI(register_android_graphics_Camera), - REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), - REG_JNI(register_android_graphics_CanvasProperty), - REG_JNI(register_android_graphics_ColorFilter), - REG_JNI(register_android_graphics_DrawFilter), - REG_JNI(register_android_graphics_FontFamily), - REG_JNI(register_android_graphics_HardwareRendererObserver), - REG_JNI(register_android_graphics_ImageDecoder), - REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable), - REG_JNI(register_android_graphics_Interpolator), - REG_JNI(register_android_graphics_MaskFilter), - REG_JNI(register_android_graphics_Matrix), - REG_JNI(register_android_graphics_Movie), - REG_JNI(register_android_graphics_NinePatch), - REG_JNI(register_android_graphics_Paint), - REG_JNI(register_android_graphics_Path), - REG_JNI(register_android_graphics_PathMeasure), - REG_JNI(register_android_graphics_PathEffect), - REG_JNI(register_android_graphics_Picture), - REG_JNI(register_android_graphics_Region), - REG_JNI(register_android_graphics_Shader), - REG_JNI(register_android_graphics_RenderEffect), - REG_JNI(register_android_graphics_TextureLayer), - REG_JNI(register_android_graphics_Typeface), - REG_JNI(register_android_graphics_YuvImage), - REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory), - REG_JNI(register_android_graphics_animation_RenderNodeAnimator), - REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable), - REG_JNI(register_android_graphics_drawable_VectorDrawable), - REG_JNI(register_android_graphics_fonts_Font), - REG_JNI(register_android_graphics_fonts_FontFamily), - REG_JNI(register_android_graphics_pdf_PdfDocument), - REG_JNI(register_android_graphics_pdf_PdfEditor), - REG_JNI(register_android_graphics_pdf_PdfRenderer), - REG_JNI(register_android_graphics_text_MeasuredText), - REG_JNI(register_android_graphics_text_LineBreaker), - REG_JNI(register_android_graphics_text_TextShaper), - - REG_JNI(register_android_util_PathParser), - REG_JNI(register_android_view_RenderNode), - REG_JNI(register_android_view_DisplayListCanvas), - REG_JNI(register_android_view_ThreadedRenderer), -}; + static const RegJNIRec gRegJNI[] = { + REG_JNI(register_android_graphics_Canvas), + // This needs to be before register_android_graphics_Graphics, or the latter + // will not be able to find the jmethodID for ColorSpace.get(). + REG_JNI(register_android_graphics_ColorSpace), + REG_JNI(register_android_graphics_Graphics), + REG_JNI(register_android_graphics_Bitmap), + REG_JNI(register_android_graphics_BitmapFactory), + REG_JNI(register_android_graphics_BitmapRegionDecoder), + REG_JNI(register_android_graphics_ByteBufferStreamAdaptor), + REG_JNI(register_android_graphics_Camera), + REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), + REG_JNI(register_android_graphics_CanvasProperty), + REG_JNI(register_android_graphics_ColorFilter), + REG_JNI(register_android_graphics_DrawFilter), + REG_JNI(register_android_graphics_FontFamily), + REG_JNI(register_android_graphics_HardwareRendererObserver), + REG_JNI(register_android_graphics_ImageDecoder), + REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable), + REG_JNI(register_android_graphics_Interpolator), + REG_JNI(register_android_graphics_MaskFilter), + REG_JNI(register_android_graphics_Matrix), + REG_JNI(register_android_graphics_Movie), + REG_JNI(register_android_graphics_NinePatch), + REG_JNI(register_android_graphics_Paint), + REG_JNI(register_android_graphics_Path), + REG_JNI(register_android_graphics_PathIterator), + REG_JNI(register_android_graphics_PathMeasure), + REG_JNI(register_android_graphics_PathEffect), + REG_JNI(register_android_graphics_Picture), + REG_JNI(register_android_graphics_Region), + REG_JNI(register_android_graphics_Shader), + REG_JNI(register_android_graphics_RenderEffect), + REG_JNI(register_android_graphics_TextureLayer), + REG_JNI(register_android_graphics_Typeface), + REG_JNI(register_android_graphics_YuvImage), + REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory), + REG_JNI(register_android_graphics_animation_RenderNodeAnimator), + REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable), + REG_JNI(register_android_graphics_drawable_VectorDrawable), + REG_JNI(register_android_graphics_fonts_Font), + REG_JNI(register_android_graphics_fonts_FontFamily), + REG_JNI(register_android_graphics_pdf_PdfDocument), + REG_JNI(register_android_graphics_pdf_PdfEditor), + REG_JNI(register_android_graphics_pdf_PdfRenderer), + REG_JNI(register_android_graphics_text_MeasuredText), + REG_JNI(register_android_graphics_text_LineBreaker), + REG_JNI(register_android_graphics_text_TextShaper), + + REG_JNI(register_android_util_PathParser), + REG_JNI(register_android_view_RenderNode), + REG_JNI(register_android_view_DisplayListCanvas), + REG_JNI(register_android_view_ThreadedRenderer), + }; } // namespace android diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h index fdc97a4fd8ba..2dcbca8273e7 100644 --- a/libs/hwui/canvas/CanvasOps.h +++ b/libs/hwui/canvas/CanvasOps.h @@ -17,13 +17,19 @@ #pragma once #include <SkAndroidFrameworkUtils.h> +#include <SkBlendMode.h> #include <SkCanvas.h> -#include <SkPath.h> -#include <SkRegion.h> -#include <SkVertices.h> +#include <SkClipOp.h> #include <SkImage.h> +#include <SkPaint.h> +#include <SkPath.h> #include <SkPicture.h> +#include <SkRRect.h> +#include <SkRect.h> +#include <SkRegion.h> #include <SkRuntimeEffect.h> +#include <SkSamplingOptions.h> +#include <SkVertices.h> #include <log/log.h> diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 67f47580a70f..feafc2372442 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -35,9 +35,15 @@ #endif #include <SkCanvas.h> +#include <SkColor.h> +#include <SkEncodedImageFormat.h> +#include <SkHighContrastFilter.h> +#include <SkImageEncoder.h> #include <SkImagePriv.h> +#include <SkPixmap.h> +#include <SkRect.h> +#include <SkStream.h> #include <SkWebpEncoder.h> -#include <SkHighContrastFilter.h> #include <limits> namespace android { diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h index 94a047c06ced..133f1fe0a1e7 100644 --- a/libs/hwui/hwui/Bitmap.h +++ b/libs/hwui/hwui/Bitmap.h @@ -19,9 +19,9 @@ #include <SkColorFilter.h> #include <SkColorSpace.h> #include <SkImage.h> -#include <SkImage.h> #include <SkImageInfo.h> #include <SkPixelRef.h> +#include <SkRefCnt.h> #include <cutils/compiler.h> #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration #include <android/hardware_buffer.h> diff --git a/libs/hwui/hwui/BlurDrawLooper.cpp b/libs/hwui/hwui/BlurDrawLooper.cpp index 270d24af99fd..d4b0198d015d 100644 --- a/libs/hwui/hwui/BlurDrawLooper.cpp +++ b/libs/hwui/hwui/BlurDrawLooper.cpp @@ -15,6 +15,7 @@ */ #include "BlurDrawLooper.h" +#include <SkColorSpace.h> #include <SkMaskFilter.h> namespace android { diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index b046f45d9c57..cd8af3d933b1 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -26,6 +26,7 @@ #include "hwui/PaintFilter.h" #include <SkFontMetrics.h> +#include <SkRRect.h> namespace android { diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index 82777646f3a2..82d23b51b12a 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -31,6 +31,7 @@ class SkAnimatedImage; class SkCanvasState; +class SkRRect; class SkRuntimeShaderBuilder; class SkVertices; @@ -151,7 +152,7 @@ public: LOG_ALWAYS_FATAL("Not supported"); } - virtual void punchHole(const SkRRect& rect) = 0; + virtual void punchHole(const SkRRect& rect, float alpha) = 0; // ---------------------------------------------------------------------------- // Canvas state operations diff --git a/libs/hwui/hwui/ImageDecoder.h b/libs/hwui/hwui/ImageDecoder.h index cef2233fc371..b6d73b39d8d0 100644 --- a/libs/hwui/hwui/ImageDecoder.h +++ b/libs/hwui/hwui/ImageDecoder.h @@ -17,9 +17,11 @@ #include <SkAndroidCodec.h> #include <SkCodec.h> +#include <SkColorSpace.h> #include <SkImageInfo.h> #include <SkPngChunkReader.h> #include <SkRect.h> +#include <SkRefCnt.h> #include <SkSize.h> #include <cutils/compiler.h> diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp index 2db3ace1cd43..34cb4aef70d9 100644 --- a/libs/hwui/hwui/MinikinSkia.cpp +++ b/libs/hwui/hwui/MinikinSkia.cpp @@ -16,10 +16,13 @@ #include "MinikinSkia.h" -#include <SkFontDescriptor.h> #include <SkFont.h> +#include <SkFontDescriptor.h> #include <SkFontMetrics.h> #include <SkFontMgr.h> +#include <SkRect.h> +#include <SkScalar.h> +#include <SkStream.h> #include <SkTypeface.h> #include <log/log.h> diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index 5a9d2508230e..3c67edc9a428 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -125,9 +125,14 @@ Typeface* Typeface::createWithDifferentBaseWeight(Typeface* src, int weight) { } Typeface* Typeface::createFromFamilies(std::vector<std::shared_ptr<minikin::FontFamily>>&& families, - int weight, int italic) { + int weight, int italic, const Typeface* fallback) { Typeface* result = new Typeface; - result->fFontCollection.reset(new minikin::FontCollection(families)); + if (fallback == nullptr) { + result->fFontCollection = minikin::FontCollection::create(std::move(families)); + } else { + result->fFontCollection = + fallback->fFontCollection->createCollectionWithFamilies(std::move(families)); + } if (weight == RESOLVE_BY_FONT_TABLE || italic == RESOLVE_BY_FONT_TABLE) { int weightFromFont; @@ -191,8 +196,8 @@ void Typeface::setRobotoTypefaceForTest() { std::vector<std::shared_ptr<minikin::Font>> fonts; fonts.push_back(minikin::Font::Builder(font).build()); - std::shared_ptr<minikin::FontCollection> collection = std::make_shared<minikin::FontCollection>( - std::make_shared<minikin::FontFamily>(std::move(fonts))); + std::shared_ptr<minikin::FontCollection> collection = + minikin::FontCollection::create(minikin::FontFamily::create(std::move(fonts))); Typeface* hwTypeface = new Typeface(); hwTypeface->fFontCollection = collection; diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h index 0c3ef01ab26b..565136e53676 100644 --- a/libs/hwui/hwui/Typeface.h +++ b/libs/hwui/hwui/Typeface.h @@ -78,7 +78,8 @@ public: Typeface* src, const std::vector<minikin::FontVariation>& variations); static Typeface* createFromFamilies( - std::vector<std::shared_ptr<minikin::FontFamily>>&& families, int weight, int italic); + std::vector<std::shared_ptr<minikin::FontFamily>>&& families, int weight, int italic, + const Typeface* fallback); static void setDefault(const Typeface* face); diff --git a/libs/hwui/jni/AnimatedImageDrawable.cpp b/libs/hwui/jni/AnimatedImageDrawable.cpp index c40b858268be..373e893b9a25 100644 --- a/libs/hwui/jni/AnimatedImageDrawable.cpp +++ b/libs/hwui/jni/AnimatedImageDrawable.cpp @@ -21,8 +21,11 @@ #include <SkAndroidCodec.h> #include <SkAnimatedImage.h> #include <SkColorFilter.h> +#include <SkEncodedImageFormat.h> #include <SkPicture.h> #include <SkPictureRecorder.h> +#include <SkRect.h> +#include <SkRefCnt.h> #include <hwui/AnimatedImageDrawable.h> #include <hwui/ImageDecoder.h> #include <hwui/Canvas.h> diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 5db0783cf83e..94cea65897cf 100755 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -2,17 +2,25 @@ #define LOG_TAG "Bitmap" #include "Bitmap.h" +#include "GraphicsJNI.h" #include "SkBitmap.h" +#include "SkBlendMode.h" #include "SkCanvas.h" #include "SkColor.h" #include "SkColorSpace.h" -#include "SkPixelRef.h" +#include "SkData.h" #include "SkImageEncoder.h" #include "SkImageInfo.h" -#include "GraphicsJNI.h" +#include "SkPaint.h" +#include "SkPixelRef.h" +#include "SkPixmap.h" +#include "SkPoint.h" +#include "SkRefCnt.h" #include "SkStream.h" +#include "SkTypes.h" #include "SkWebpEncoder.h" + #include "android_nio_utils.h" #include "CreateJavaOutputStreamAdaptor.h" #include <hwui/Paint.h> diff --git a/libs/hwui/jni/Bitmap.h b/libs/hwui/jni/Bitmap.h index 73eca3aa8ef8..21a93f066d9b 100644 --- a/libs/hwui/jni/Bitmap.h +++ b/libs/hwui/jni/Bitmap.h @@ -19,7 +19,6 @@ #include <jni.h> #include <android/bitmap.h> -class SkBitmap; struct SkImageInfo; namespace android { diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp index 4e9daa4b0c16..320d3322904f 100644 --- a/libs/hwui/jni/BitmapFactory.cpp +++ b/libs/hwui/jni/BitmapFactory.cpp @@ -8,9 +8,19 @@ #include "MimeType.h" #include "NinePatchPeeker.h" #include "SkAndroidCodec.h" +#include "SkBitmap.h" +#include "SkBlendMode.h" #include "SkCanvas.h" +#include "SkColorSpace.h" +#include "SkEncodedImageFormat.h" +#include "SkImageInfo.h" #include "SkMath.h" +#include "SkPaint.h" #include "SkPixelRef.h" +#include "SkRect.h" +#include "SkRefCnt.h" +#include "SkSamplingOptions.h" +#include "SkSize.h" #include "SkStream.h" #include "SkString.h" #include "SkUtils.h" diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp index 1c20415dcc8f..eb56ae310231 100644 --- a/libs/hwui/jni/BitmapRegionDecoder.cpp +++ b/libs/hwui/jni/BitmapRegionDecoder.cpp @@ -25,6 +25,7 @@ #include "BitmapRegionDecoder.h" #include "SkBitmap.h" #include "SkCodec.h" +#include "SkColorSpace.h" #include "SkData.h" #include "SkStream.h" diff --git a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp index b10540cb3fbd..97dbc9ac171f 100644 --- a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp +++ b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp @@ -2,6 +2,7 @@ #include "GraphicsJNI.h" #include "Utils.h" +#include <SkData.h> #include <SkStream.h> using namespace android; diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp index ce5ac382aeff..c146adac6b69 100644 --- a/libs/hwui/jni/FontFamily.cpp +++ b/libs/hwui/jni/FontFamily.cpp @@ -24,6 +24,7 @@ #include "SkData.h" #include "SkFontMgr.h" #include "SkRefCnt.h" +#include "SkStream.h" #include "SkTypeface.h" #include "Utils.h" #include "fonts/Font.h" @@ -84,9 +85,9 @@ static jlong FontFamily_create(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr) { if (builder->fonts.empty()) { return 0; } - std::shared_ptr<minikin::FontFamily> family = std::make_shared<minikin::FontFamily>( - builder->langId, builder->variant, std::move(builder->fonts), - true /* isCustomFallback */); + std::shared_ptr<minikin::FontFamily> family = + minikin::FontFamily::create(builder->langId, builder->variant, + std::move(builder->fonts), true /* isCustomFallback */); if (family->getCoverage().length() == 0) { return 0; } diff --git a/libs/hwui/jni/GIFMovie.cpp b/libs/hwui/jni/GIFMovie.cpp index fef51b8d2f79..ae6ac4ce4ecc 100644 --- a/libs/hwui/jni/GIFMovie.cpp +++ b/libs/hwui/jni/GIFMovie.cpp @@ -7,9 +7,11 @@ #include "Movie.h" +#include "SkBitmap.h" #include "SkColor.h" #include "SkColorPriv.h" #include "SkStream.h" +#include "SkTypes.h" #include "gif_lib.h" diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp index 33669ac0a34e..6a3bc8fe1152 100644 --- a/libs/hwui/jni/Graphics.cpp +++ b/libs/hwui/jni/Graphics.cpp @@ -8,10 +8,18 @@ #include <nativehelper/JNIHelp.h> #include "GraphicsJNI.h" +#include "include/private/SkTemplates.h" // SkTAddOffset +#include "SkBitmap.h" #include "SkCanvas.h" +#include "SkColorSpace.h" #include "SkFontMetrics.h" +#include "SkImageInfo.h" #include "SkMath.h" +#include "SkPixelRef.h" +#include "SkPoint.h" +#include "SkRect.h" #include "SkRegion.h" +#include "SkTypes.h" #include <cutils/ashmem.h> #include <hwui/Canvas.h> diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp index f7b8c014be6e..bad710dec274 100644 --- a/libs/hwui/jni/ImageDecoder.cpp +++ b/libs/hwui/jni/ImageDecoder.cpp @@ -29,8 +29,12 @@ #include <FrontBufferedStream.h> #include <SkAndroidCodec.h> -#include <SkEncodedImageFormat.h> +#include <SkBitmap.h> +#include <SkColorSpace.h> +#include <SkImageInfo.h> +#include <SkRect.h> #include <SkStream.h> +#include <SkString.h> #include <androidfw/Asset.h> #include <fcntl.h> diff --git a/libs/hwui/jni/Movie.h b/libs/hwui/jni/Movie.h index 736890d5215e..02113dd58ec8 100644 --- a/libs/hwui/jni/Movie.h +++ b/libs/hwui/jni/Movie.h @@ -13,6 +13,7 @@ #include "SkBitmap.h" #include "SkCanvas.h" #include "SkRefCnt.h" +#include "SkTypes.h" class SkStreamRewindable; diff --git a/libs/hwui/jni/MovieImpl.cpp b/libs/hwui/jni/MovieImpl.cpp index ae9e04e617b0..abb75fa99c94 100644 --- a/libs/hwui/jni/MovieImpl.cpp +++ b/libs/hwui/jni/MovieImpl.cpp @@ -5,11 +5,12 @@ * found in the LICENSE file. */ #include "Movie.h" -#include "SkCanvas.h" -#include "SkPaint.h" +#include "SkBitmap.h" +#include "SkStream.h" +#include "SkTypes.h" // We should never see this in normal operation since our time values are -// 0-based. So we use it as a sentinal. +// 0-based. So we use it as a sentinel. #define UNINITIALIZED_MSEC ((SkMSec)-1) Movie::Movie() @@ -81,8 +82,6 @@ const SkBitmap& Movie::bitmap() //////////////////////////////////////////////////////////////////// -#include "SkStream.h" - Movie* Movie::DecodeMemory(const void* data, size_t length) { SkMemoryStream stream(data, length, false); return Movie::DecodeStream(&stream); diff --git a/libs/hwui/jni/NinePatch.cpp b/libs/hwui/jni/NinePatch.cpp index 08fc80fbdafd..d50a8a22b5cb 100644 --- a/libs/hwui/jni/NinePatch.cpp +++ b/libs/hwui/jni/NinePatch.cpp @@ -24,8 +24,10 @@ #include <hwui/Paint.h> #include <utils/Log.h> +#include "SkBitmap.h" #include "SkCanvas.h" #include "SkLatticeIter.h" +#include "SkRect.h" #include "SkRegion.h" #include "GraphicsJNI.h" #include "NinePatchPeeker.h" diff --git a/libs/hwui/jni/NinePatchPeeker.cpp b/libs/hwui/jni/NinePatchPeeker.cpp index 9171fc687276..d85ede5dc6d2 100644 --- a/libs/hwui/jni/NinePatchPeeker.cpp +++ b/libs/hwui/jni/NinePatchPeeker.cpp @@ -16,7 +16,7 @@ #include "NinePatchPeeker.h" -#include <SkBitmap.h> +#include <SkScalar.h> #include <cutils/compiler.h> using namespace android; diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index f76863255153..f0a4bd0f00f0 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -26,6 +26,7 @@ #include <nativehelper/ScopedPrimitiveArray.h> #include "SkColorFilter.h" +#include "SkColorSpace.h" #include "SkFont.h" #include "SkFontMetrics.h" #include "SkFontTypes.h" @@ -496,17 +497,32 @@ namespace PaintGlue { return true; } - static jfloat doRunAdvance(const Paint* paint, const Typeface* typeface, const jchar buf[], - jint start, jint count, jint bufSize, jboolean isRtl, jint offset) { + static jfloat doRunAdvance(JNIEnv* env, const Paint* paint, const Typeface* typeface, + const jchar buf[], jint start, jint count, jint bufSize, + jboolean isRtl, jint offset, jfloatArray advances, + jint advancesIndex) { + if (advances) { + size_t advancesLength = env->GetArrayLength(advances); + if ((size_t)(count + advancesIndex) > advancesLength) { + doThrowAIOOBE(env); + return 0; + } + } minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; - if (offset == start + count) { + if (offset == start + count && advances == nullptr) { return MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize, nullptr); } std::unique_ptr<float[]> advancesArray(new float[count]); MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize, advancesArray.get()); - return minikin::getRunAdvance(advancesArray.get(), buf, start, count, offset); + + float result = minikin::getRunAdvance(advancesArray.get(), buf, start, count, offset); + if (advances) { + minikin::distributeAdvances(advancesArray.get(), buf, start, count); + env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get()); + } + return result; } static jfloat getRunAdvance___CIIIIZI_F(JNIEnv *env, jclass, jlong paintHandle, jcharArray text, @@ -514,9 +530,23 @@ namespace PaintGlue { const Paint* paint = reinterpret_cast<Paint*>(paintHandle); const Typeface* typeface = paint->getAndroidTypeface(); ScopedCharArrayRO textArray(env, text); - jfloat result = doRunAdvance(paint, typeface, textArray.get() + contextStart, - start - contextStart, end - start, contextEnd - contextStart, isRtl, - offset - contextStart); + jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart, + start - contextStart, end - start, contextEnd - contextStart, + isRtl, offset - contextStart, nullptr, 0); + return result; + } + + static jfloat getRunCharacterAdvance___CIIIIZI_FI_F(JNIEnv* env, jclass, jlong paintHandle, + jcharArray text, jint start, jint end, + jint contextStart, jint contextEnd, + jboolean isRtl, jint offset, + jfloatArray advances, jint advancesIndex) { + const Paint* paint = reinterpret_cast<Paint*>(paintHandle); + const Typeface* typeface = paint->getAndroidTypeface(); + ScopedCharArrayRO textArray(env, text); + jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart, + start - contextStart, end - start, contextEnd - contextStart, + isRtl, offset - contextStart, advances, advancesIndex); return result; } @@ -1033,113 +1063,112 @@ namespace PaintGlue { }; // namespace PaintGlue static const JNINativeMethod methods[] = { - {"nGetNativeFinalizer", "()J", (void*) PaintGlue::getNativeFinalizer}, - {"nInit","()J", (void*) PaintGlue::init}, - {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint}, - {"nBreakText","(J[CIIFI[F)I", (void*) PaintGlue::breakTextC}, - {"nBreakText","(JLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS}, - {"nGetTextAdvances","(J[CIIIII[FI)F", - (void*) PaintGlue::getTextAdvances___CIIIII_FI}, - {"nGetTextAdvances","(JLjava/lang/String;IIIII[FI)F", - (void*) PaintGlue::getTextAdvances__StringIIIII_FI}, - - {"nGetTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, - {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I", - (void*) PaintGlue::getTextRunCursor__String}, - {"nGetTextPath", "(JI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C}, - {"nGetTextPath", "(JILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String}, - {"nGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V", - (void*) PaintGlue::getStringBounds }, - {"nGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V", - (void*) PaintGlue::getCharArrayBounds }, - {"nHasGlyph", "(JILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph }, - {"nGetRunAdvance", "(J[CIIIIZI)F", (void*) PaintGlue::getRunAdvance___CIIIIZI_F}, - {"nGetOffsetForAdvance", "(J[CIIIIZF)I", - (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I}, - {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V", - (void*)PaintGlue::getFontMetricsIntForText___C}, - {"nGetFontMetricsIntForText", - "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V", - (void*)PaintGlue::getFontMetricsIntForText___String}, - - // --------------- @FastNative ---------------------- - - {"nSetTextLocales","(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales}, - {"nSetFontFeatureSettings","(JLjava/lang/String;)V", - (void*) PaintGlue::setFontFeatureSettings}, - {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F", - (void*)PaintGlue::getFontMetrics}, - {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I", - (void*)PaintGlue::getFontMetricsInt}, - - // --------------- @CriticalNative ------------------ - - {"nReset","(J)V", (void*) PaintGlue::reset}, - {"nSet","(JJ)V", (void*) PaintGlue::assign}, - {"nGetFlags","(J)I", (void*) PaintGlue::getFlags}, - {"nSetFlags","(JI)V", (void*) PaintGlue::setFlags}, - {"nGetHinting","(J)I", (void*) PaintGlue::getHinting}, - {"nSetHinting","(JI)V", (void*) PaintGlue::setHinting}, - {"nSetAntiAlias","(JZ)V", (void*) PaintGlue::setAntiAlias}, - {"nSetSubpixelText","(JZ)V", (void*) PaintGlue::setSubpixelText}, - {"nSetLinearText","(JZ)V", (void*) PaintGlue::setLinearText}, - {"nSetUnderlineText","(JZ)V", (void*) PaintGlue::setUnderlineText}, - {"nSetStrikeThruText","(JZ)V", (void*) PaintGlue::setStrikeThruText}, - {"nSetFakeBoldText","(JZ)V", (void*) PaintGlue::setFakeBoldText}, - {"nSetFilterBitmap","(JZ)V", (void*) PaintGlue::setFilterBitmap}, - {"nSetDither","(JZ)V", (void*) PaintGlue::setDither}, - {"nGetStyle","(J)I", (void*) PaintGlue::getStyle}, - {"nSetStyle","(JI)V", (void*) PaintGlue::setStyle}, - {"nSetColor","(JI)V", (void*) PaintGlue::setColor}, - {"nSetColor","(JJJ)V", (void*) PaintGlue::setColorLong}, - {"nSetAlpha","(JI)V", (void*) PaintGlue::setAlpha}, - {"nGetStrokeWidth","(J)F", (void*) PaintGlue::getStrokeWidth}, - {"nSetStrokeWidth","(JF)V", (void*) PaintGlue::setStrokeWidth}, - {"nGetStrokeMiter","(J)F", (void*) PaintGlue::getStrokeMiter}, - {"nSetStrokeMiter","(JF)V", (void*) PaintGlue::setStrokeMiter}, - {"nGetStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap}, - {"nSetStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap}, - {"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin}, - {"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin}, - {"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath}, - {"nSetShader","(JJ)J", (void*) PaintGlue::setShader}, - {"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter}, - {"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode}, - {"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect}, - {"nSetMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter}, - {"nSetTypeface","(JJ)V", (void*) PaintGlue::setTypeface}, - {"nGetTextAlign","(J)I", (void*) PaintGlue::getTextAlign}, - {"nSetTextAlign","(JI)V", (void*) PaintGlue::setTextAlign}, - {"nSetTextLocalesByMinikinLocaleListId","(JI)V", - (void*) PaintGlue::setTextLocalesByMinikinLocaleListId}, - {"nIsElegantTextHeight","(J)Z", (void*) PaintGlue::isElegantTextHeight}, - {"nSetElegantTextHeight","(JZ)V", (void*) PaintGlue::setElegantTextHeight}, - {"nGetTextSize","(J)F", (void*) PaintGlue::getTextSize}, - {"nSetTextSize","(JF)V", (void*) PaintGlue::setTextSize}, - {"nGetTextScaleX","(J)F", (void*) PaintGlue::getTextScaleX}, - {"nSetTextScaleX","(JF)V", (void*) PaintGlue::setTextScaleX}, - {"nGetTextSkewX","(J)F", (void*) PaintGlue::getTextSkewX}, - {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX}, - {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing}, - {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing}, - {"nGetWordSpacing","(J)F", (void*) PaintGlue::getWordSpacing}, - {"nSetWordSpacing","(JF)V", (void*) PaintGlue::setWordSpacing}, - {"nGetStartHyphenEdit", "(J)I", (void*) PaintGlue::getStartHyphenEdit}, - {"nGetEndHyphenEdit", "(J)I", (void*) PaintGlue::getEndHyphenEdit}, - {"nSetStartHyphenEdit", "(JI)V", (void*) PaintGlue::setStartHyphenEdit}, - {"nSetEndHyphenEdit", "(JI)V", (void*) PaintGlue::setEndHyphenEdit}, - {"nAscent","(J)F", (void*) PaintGlue::ascent}, - {"nDescent","(J)F", (void*) PaintGlue::descent}, - {"nGetUnderlinePosition","(J)F", (void*) PaintGlue::getUnderlinePosition}, - {"nGetUnderlineThickness","(J)F", (void*) PaintGlue::getUnderlineThickness}, - {"nGetStrikeThruPosition","(J)F", (void*) PaintGlue::getStrikeThruPosition}, - {"nGetStrikeThruThickness","(J)F", (void*) PaintGlue::getStrikeThruThickness}, - {"nSetShadowLayer", "(JFFFJJ)V", (void*)PaintGlue::setShadowLayer}, - {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer}, - {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement}, + {"nGetNativeFinalizer", "()J", (void*)PaintGlue::getNativeFinalizer}, + {"nInit", "()J", (void*)PaintGlue::init}, + {"nInitWithPaint", "(J)J", (void*)PaintGlue::initWithPaint}, + {"nBreakText", "(J[CIIFI[F)I", (void*)PaintGlue::breakTextC}, + {"nBreakText", "(JLjava/lang/String;ZFI[F)I", (void*)PaintGlue::breakTextS}, + {"nGetTextAdvances", "(J[CIIIII[FI)F", (void*)PaintGlue::getTextAdvances___CIIIII_FI}, + {"nGetTextAdvances", "(JLjava/lang/String;IIIII[FI)F", + (void*)PaintGlue::getTextAdvances__StringIIIII_FI}, + + {"nGetTextRunCursor", "(J[CIIIII)I", (void*)PaintGlue::getTextRunCursor___C}, + {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I", + (void*)PaintGlue::getTextRunCursor__String}, + {"nGetTextPath", "(JI[CIIFFJ)V", (void*)PaintGlue::getTextPath___C}, + {"nGetTextPath", "(JILjava/lang/String;IIFFJ)V", (void*)PaintGlue::getTextPath__String}, + {"nGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V", + (void*)PaintGlue::getStringBounds}, + {"nGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V", + (void*)PaintGlue::getCharArrayBounds}, + {"nHasGlyph", "(JILjava/lang/String;)Z", (void*)PaintGlue::hasGlyph}, + {"nGetRunAdvance", "(J[CIIIIZI)F", (void*)PaintGlue::getRunAdvance___CIIIIZI_F}, + {"nGetRunCharacterAdvance", "(J[CIIIIZI[FI)F", + (void*)PaintGlue::getRunCharacterAdvance___CIIIIZI_FI_F}, + {"nGetOffsetForAdvance", "(J[CIIIIZF)I", (void*)PaintGlue::getOffsetForAdvance___CIIIIZF_I}, + {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V", + (void*)PaintGlue::getFontMetricsIntForText___C}, + {"nGetFontMetricsIntForText", + "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V", + (void*)PaintGlue::getFontMetricsIntForText___String}, + + // --------------- @FastNative ---------------------- + + {"nSetTextLocales", "(JLjava/lang/String;)I", (void*)PaintGlue::setTextLocales}, + {"nSetFontFeatureSettings", "(JLjava/lang/String;)V", + (void*)PaintGlue::setFontFeatureSettings}, + {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F", + (void*)PaintGlue::getFontMetrics}, + {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I", + (void*)PaintGlue::getFontMetricsInt}, + + // --------------- @CriticalNative ------------------ + + {"nReset", "(J)V", (void*)PaintGlue::reset}, + {"nSet", "(JJ)V", (void*)PaintGlue::assign}, + {"nGetFlags", "(J)I", (void*)PaintGlue::getFlags}, + {"nSetFlags", "(JI)V", (void*)PaintGlue::setFlags}, + {"nGetHinting", "(J)I", (void*)PaintGlue::getHinting}, + {"nSetHinting", "(JI)V", (void*)PaintGlue::setHinting}, + {"nSetAntiAlias", "(JZ)V", (void*)PaintGlue::setAntiAlias}, + {"nSetSubpixelText", "(JZ)V", (void*)PaintGlue::setSubpixelText}, + {"nSetLinearText", "(JZ)V", (void*)PaintGlue::setLinearText}, + {"nSetUnderlineText", "(JZ)V", (void*)PaintGlue::setUnderlineText}, + {"nSetStrikeThruText", "(JZ)V", (void*)PaintGlue::setStrikeThruText}, + {"nSetFakeBoldText", "(JZ)V", (void*)PaintGlue::setFakeBoldText}, + {"nSetFilterBitmap", "(JZ)V", (void*)PaintGlue::setFilterBitmap}, + {"nSetDither", "(JZ)V", (void*)PaintGlue::setDither}, + {"nGetStyle", "(J)I", (void*)PaintGlue::getStyle}, + {"nSetStyle", "(JI)V", (void*)PaintGlue::setStyle}, + {"nSetColor", "(JI)V", (void*)PaintGlue::setColor}, + {"nSetColor", "(JJJ)V", (void*)PaintGlue::setColorLong}, + {"nSetAlpha", "(JI)V", (void*)PaintGlue::setAlpha}, + {"nGetStrokeWidth", "(J)F", (void*)PaintGlue::getStrokeWidth}, + {"nSetStrokeWidth", "(JF)V", (void*)PaintGlue::setStrokeWidth}, + {"nGetStrokeMiter", "(J)F", (void*)PaintGlue::getStrokeMiter}, + {"nSetStrokeMiter", "(JF)V", (void*)PaintGlue::setStrokeMiter}, + {"nGetStrokeCap", "(J)I", (void*)PaintGlue::getStrokeCap}, + {"nSetStrokeCap", "(JI)V", (void*)PaintGlue::setStrokeCap}, + {"nGetStrokeJoin", "(J)I", (void*)PaintGlue::getStrokeJoin}, + {"nSetStrokeJoin", "(JI)V", (void*)PaintGlue::setStrokeJoin}, + {"nGetFillPath", "(JJJ)Z", (void*)PaintGlue::getFillPath}, + {"nSetShader", "(JJ)J", (void*)PaintGlue::setShader}, + {"nSetColorFilter", "(JJ)J", (void*)PaintGlue::setColorFilter}, + {"nSetXfermode", "(JI)V", (void*)PaintGlue::setXfermode}, + {"nSetPathEffect", "(JJ)J", (void*)PaintGlue::setPathEffect}, + {"nSetMaskFilter", "(JJ)J", (void*)PaintGlue::setMaskFilter}, + {"nSetTypeface", "(JJ)V", (void*)PaintGlue::setTypeface}, + {"nGetTextAlign", "(J)I", (void*)PaintGlue::getTextAlign}, + {"nSetTextAlign", "(JI)V", (void*)PaintGlue::setTextAlign}, + {"nSetTextLocalesByMinikinLocaleListId", "(JI)V", + (void*)PaintGlue::setTextLocalesByMinikinLocaleListId}, + {"nIsElegantTextHeight", "(J)Z", (void*)PaintGlue::isElegantTextHeight}, + {"nSetElegantTextHeight", "(JZ)V", (void*)PaintGlue::setElegantTextHeight}, + {"nGetTextSize", "(J)F", (void*)PaintGlue::getTextSize}, + {"nSetTextSize", "(JF)V", (void*)PaintGlue::setTextSize}, + {"nGetTextScaleX", "(J)F", (void*)PaintGlue::getTextScaleX}, + {"nSetTextScaleX", "(JF)V", (void*)PaintGlue::setTextScaleX}, + {"nGetTextSkewX", "(J)F", (void*)PaintGlue::getTextSkewX}, + {"nSetTextSkewX", "(JF)V", (void*)PaintGlue::setTextSkewX}, + {"nGetLetterSpacing", "(J)F", (void*)PaintGlue::getLetterSpacing}, + {"nSetLetterSpacing", "(JF)V", (void*)PaintGlue::setLetterSpacing}, + {"nGetWordSpacing", "(J)F", (void*)PaintGlue::getWordSpacing}, + {"nSetWordSpacing", "(JF)V", (void*)PaintGlue::setWordSpacing}, + {"nGetStartHyphenEdit", "(J)I", (void*)PaintGlue::getStartHyphenEdit}, + {"nGetEndHyphenEdit", "(J)I", (void*)PaintGlue::getEndHyphenEdit}, + {"nSetStartHyphenEdit", "(JI)V", (void*)PaintGlue::setStartHyphenEdit}, + {"nSetEndHyphenEdit", "(JI)V", (void*)PaintGlue::setEndHyphenEdit}, + {"nAscent", "(J)F", (void*)PaintGlue::ascent}, + {"nDescent", "(J)F", (void*)PaintGlue::descent}, + {"nGetUnderlinePosition", "(J)F", (void*)PaintGlue::getUnderlinePosition}, + {"nGetUnderlineThickness", "(J)F", (void*)PaintGlue::getUnderlineThickness}, + {"nGetStrikeThruPosition", "(J)F", (void*)PaintGlue::getStrikeThruPosition}, + {"nGetStrikeThruThickness", "(J)F", (void*)PaintGlue::getStrikeThruThickness}, + {"nSetShadowLayer", "(JFFFJJ)V", (void*)PaintGlue::setShadowLayer}, + {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer}, + {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement}, }; - int register_android_graphics_Paint(JNIEnv* env) { return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods)); } diff --git a/libs/hwui/jni/Path.cpp b/libs/hwui/jni/Path.cpp index d67bcf221681..3694ce07b972 100644 --- a/libs/hwui/jni/Path.cpp +++ b/libs/hwui/jni/Path.cpp @@ -102,6 +102,18 @@ public: obj->rQuadTo(dx1, dy1, dx2, dy2); } + static void conicTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, + jfloat y2, jfloat weight) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + obj->conicTo(x1, y1, x2, y2, weight); + } + + static void rConicTo(JNIEnv* env, jclass clazz, jlong objHandle, jfloat dx1, jfloat dy1, + jfloat dx2, jfloat dy2, jfloat weight) { + SkPath* obj = reinterpret_cast<SkPath*>(objHandle); + obj->rConicTo(dx1, dy1, dx2, dy2, weight); + } + static void cubicTo__FFFFFF(JNIEnv* env, jclass clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2, jfloat x3, jfloat y3) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); @@ -209,6 +221,14 @@ public: obj->setLastPt(dx, dy); } + static jboolean interpolate(JNIEnv* env, jclass clazz, jlong startHandle, jlong endHandle, + jfloat t, jlong interpolatedHandle) { + SkPath* startPath = reinterpret_cast<SkPath*>(startHandle); + SkPath* endPath = reinterpret_cast<SkPath*>(endHandle); + SkPath* interpolatedPath = reinterpret_cast<SkPath*>(interpolatedHandle); + return startPath->interpolate(*endPath, t, interpolatedPath); + } + static void transform__MatrixPath(JNIEnv* env, jclass clazz, jlong objHandle, jlong matrixHandle, jlong dstHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); @@ -473,6 +493,16 @@ public: // ---------------- @CriticalNative ------------------------- + static jint getGenerationID(CRITICAL_JNI_PARAMS_COMMA jlong pathHandle) { + return (reinterpret_cast<SkPath*>(pathHandle)->getGenerationID()); + } + + static jboolean isInterpolatable(CRITICAL_JNI_PARAMS_COMMA jlong startHandle, jlong endHandle) { + SkPath* startPath = reinterpret_cast<SkPath*>(startHandle); + SkPath* endPath = reinterpret_cast<SkPath*>(endHandle); + return startPath->isInterpolatable(*endPath); + } + static void reset(CRITICAL_JNI_PARAMS_COMMA jlong objHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->reset(); @@ -506,48 +536,53 @@ public: }; static const JNINativeMethod methods[] = { - {"nInit","()J", (void*) SkPathGlue::init}, - {"nInit","(J)J", (void*) SkPathGlue::init_Path}, - {"nGetFinalizer", "()J", (void*) SkPathGlue::getFinalizer}, - {"nSet","(JJ)V", (void*) SkPathGlue::set}, - {"nComputeBounds","(JLandroid/graphics/RectF;)V", (void*) SkPathGlue::computeBounds}, - {"nIncReserve","(JI)V", (void*) SkPathGlue::incReserve}, - {"nMoveTo","(JFF)V", (void*) SkPathGlue::moveTo__FF}, - {"nRMoveTo","(JFF)V", (void*) SkPathGlue::rMoveTo}, - {"nLineTo","(JFF)V", (void*) SkPathGlue::lineTo__FF}, - {"nRLineTo","(JFF)V", (void*) SkPathGlue::rLineTo}, - {"nQuadTo","(JFFFF)V", (void*) SkPathGlue::quadTo__FFFF}, - {"nRQuadTo","(JFFFF)V", (void*) SkPathGlue::rQuadTo}, - {"nCubicTo","(JFFFFFF)V", (void*) SkPathGlue::cubicTo__FFFFFF}, - {"nRCubicTo","(JFFFFFF)V", (void*) SkPathGlue::rCubicTo}, - {"nArcTo","(JFFFFFFZ)V", (void*) SkPathGlue::arcTo}, - {"nClose","(J)V", (void*) SkPathGlue::close}, - {"nAddRect","(JFFFFI)V", (void*) SkPathGlue::addRect}, - {"nAddOval","(JFFFFI)V", (void*) SkPathGlue::addOval}, - {"nAddCircle","(JFFFI)V", (void*) SkPathGlue::addCircle}, - {"nAddArc","(JFFFFFF)V", (void*) SkPathGlue::addArc}, - {"nAddRoundRect","(JFFFFFFI)V", (void*) SkPathGlue::addRoundRectXY}, - {"nAddRoundRect","(JFFFF[FI)V", (void*) SkPathGlue::addRoundRect8}, - {"nAddPath","(JJFF)V", (void*) SkPathGlue::addPath__PathFF}, - {"nAddPath","(JJ)V", (void*) SkPathGlue::addPath__Path}, - {"nAddPath","(JJJ)V", (void*) SkPathGlue::addPath__PathMatrix}, - {"nOffset","(JFF)V", (void*) SkPathGlue::offset__FF}, - {"nSetLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint}, - {"nTransform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath}, - {"nTransform","(JJ)V", (void*) SkPathGlue::transform__Matrix}, - {"nOp","(JJIJ)Z", (void*) SkPathGlue::op}, - {"nApproximate", "(JF)[F", (void*) SkPathGlue::approximate}, - - // ------- @FastNative below here ---------------------- - {"nIsRect","(JLandroid/graphics/RectF;)Z", (void*) SkPathGlue::isRect}, - - // ------- @CriticalNative below here ------------------ - {"nReset","(J)V", (void*) SkPathGlue::reset}, - {"nRewind","(J)V", (void*) SkPathGlue::rewind}, - {"nIsEmpty","(J)Z", (void*) SkPathGlue::isEmpty}, - {"nIsConvex","(J)Z", (void*) SkPathGlue::isConvex}, - {"nGetFillType","(J)I", (void*) SkPathGlue::getFillType}, - {"nSetFillType","(JI)V", (void*) SkPathGlue::setFillType}, + {"nInit", "()J", (void*)SkPathGlue::init}, + {"nInit", "(J)J", (void*)SkPathGlue::init_Path}, + {"nGetFinalizer", "()J", (void*)SkPathGlue::getFinalizer}, + {"nSet", "(JJ)V", (void*)SkPathGlue::set}, + {"nComputeBounds", "(JLandroid/graphics/RectF;)V", (void*)SkPathGlue::computeBounds}, + {"nIncReserve", "(JI)V", (void*)SkPathGlue::incReserve}, + {"nMoveTo", "(JFF)V", (void*)SkPathGlue::moveTo__FF}, + {"nRMoveTo", "(JFF)V", (void*)SkPathGlue::rMoveTo}, + {"nLineTo", "(JFF)V", (void*)SkPathGlue::lineTo__FF}, + {"nRLineTo", "(JFF)V", (void*)SkPathGlue::rLineTo}, + {"nQuadTo", "(JFFFF)V", (void*)SkPathGlue::quadTo__FFFF}, + {"nRQuadTo", "(JFFFF)V", (void*)SkPathGlue::rQuadTo}, + {"nConicTo", "(JFFFFF)V", (void*)SkPathGlue::conicTo}, + {"nRConicTo", "(JFFFFF)V", (void*)SkPathGlue::rConicTo}, + {"nCubicTo", "(JFFFFFF)V", (void*)SkPathGlue::cubicTo__FFFFFF}, + {"nRCubicTo", "(JFFFFFF)V", (void*)SkPathGlue::rCubicTo}, + {"nArcTo", "(JFFFFFFZ)V", (void*)SkPathGlue::arcTo}, + {"nClose", "(J)V", (void*)SkPathGlue::close}, + {"nAddRect", "(JFFFFI)V", (void*)SkPathGlue::addRect}, + {"nAddOval", "(JFFFFI)V", (void*)SkPathGlue::addOval}, + {"nAddCircle", "(JFFFI)V", (void*)SkPathGlue::addCircle}, + {"nAddArc", "(JFFFFFF)V", (void*)SkPathGlue::addArc}, + {"nAddRoundRect", "(JFFFFFFI)V", (void*)SkPathGlue::addRoundRectXY}, + {"nAddRoundRect", "(JFFFF[FI)V", (void*)SkPathGlue::addRoundRect8}, + {"nAddPath", "(JJFF)V", (void*)SkPathGlue::addPath__PathFF}, + {"nAddPath", "(JJ)V", (void*)SkPathGlue::addPath__Path}, + {"nAddPath", "(JJJ)V", (void*)SkPathGlue::addPath__PathMatrix}, + {"nInterpolate", "(JJFJ)Z", (void*)SkPathGlue::interpolate}, + {"nOffset", "(JFF)V", (void*)SkPathGlue::offset__FF}, + {"nSetLastPoint", "(JFF)V", (void*)SkPathGlue::setLastPoint}, + {"nTransform", "(JJJ)V", (void*)SkPathGlue::transform__MatrixPath}, + {"nTransform", "(JJ)V", (void*)SkPathGlue::transform__Matrix}, + {"nOp", "(JJIJ)Z", (void*)SkPathGlue::op}, + {"nApproximate", "(JF)[F", (void*)SkPathGlue::approximate}, + + // ------- @FastNative below here ---------------------- + {"nIsRect", "(JLandroid/graphics/RectF;)Z", (void*)SkPathGlue::isRect}, + + // ------- @CriticalNative below here ------------------ + {"nGetGenerationID", "(J)I", (void*)SkPathGlue::getGenerationID}, + {"nIsInterpolatable", "(JJ)Z", (void*)SkPathGlue::isInterpolatable}, + {"nReset", "(J)V", (void*)SkPathGlue::reset}, + {"nRewind", "(J)V", (void*)SkPathGlue::rewind}, + {"nIsEmpty", "(J)Z", (void*)SkPathGlue::isEmpty}, + {"nIsConvex", "(J)Z", (void*)SkPathGlue::isConvex}, + {"nGetFillType", "(J)I", (void*)SkPathGlue::getFillType}, + {"nSetFillType", "(JI)V", (void*)SkPathGlue::setFillType}, }; int register_android_graphics_Path(JNIEnv* env) { diff --git a/libs/hwui/jni/PathIterator.cpp b/libs/hwui/jni/PathIterator.cpp new file mode 100644 index 000000000000..3884342d8d37 --- /dev/null +++ b/libs/hwui/jni/PathIterator.cpp @@ -0,0 +1,81 @@ +/* libs/android_runtime/android/graphics/PathMeasure.cpp +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT 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 <log/log.h> + +#include "GraphicsJNI.h" +#include "SkPath.h" +#include "SkPoint.h" + +namespace android { + +class SkPathIteratorGlue { +public: + static void finalizer(SkPath::RawIter* obj) { delete obj; } + + static jlong getFinalizer(JNIEnv* env, jclass clazz) { + return static_cast<jlong>(reinterpret_cast<uintptr_t>(&finalizer)); + } + + static jlong create(JNIEnv* env, jobject clazz, jlong pathHandle) { + const SkPath* path = reinterpret_cast<SkPath*>(pathHandle); + return reinterpret_cast<jlong>(new SkPath::RawIter(*path)); + } + + // ---------------- @CriticalNative ------------------------- + + static jint peek(CRITICAL_JNI_PARAMS_COMMA jlong iteratorHandle) { + SkPath::RawIter* iterator = reinterpret_cast<SkPath::RawIter*>(iteratorHandle); + return iterator->peek(); + } + + static jint next(CRITICAL_JNI_PARAMS_COMMA jlong iteratorHandle, jlong pointsArray) { + static_assert(SkPath::kMove_Verb == 0, "SkPath::Verb unexpected index"); + static_assert(SkPath::kLine_Verb == 1, "SkPath::Verb unexpected index"); + static_assert(SkPath::kQuad_Verb == 2, "SkPath::Verb unexpected index"); + static_assert(SkPath::kConic_Verb == 3, "SkPath::Verb unexpected index"); + static_assert(SkPath::kCubic_Verb == 4, "SkPath::Verb unexpected index"); + static_assert(SkPath::kClose_Verb == 5, "SkPath::Verb unexpected index"); + static_assert(SkPath::kDone_Verb == 6, "SkPath::Verb unexpected index"); + + SkPath::RawIter* iterator = reinterpret_cast<SkPath::RawIter*>(iteratorHandle); + float* points = reinterpret_cast<float*>(pointsArray); + SkPath::Verb verb = + static_cast<SkPath::Verb>(iterator->next(reinterpret_cast<SkPoint*>(points))); + if (verb == SkPath::kConic_Verb) { + float weight = iterator->conicWeight(); + points[6] = weight; + } + return static_cast<int>(verb); + } +}; + +static const JNINativeMethod methods[] = { + {"nCreate", "(J)J", (void*)SkPathIteratorGlue::create}, + {"nGetFinalizer", "()J", (void*)SkPathIteratorGlue::getFinalizer}, + + // ------- @CriticalNative below here ------------------ + + {"nPeek", "(J)I", (void*)SkPathIteratorGlue::peek}, + {"nNext", "(JJ)I", (void*)SkPathIteratorGlue::next}, +}; + +int register_android_graphics_PathIterator(JNIEnv* env) { + return RegisterMethodsOrDie(env, "android/graphics/PathIterator", methods, NELEM(methods)); +} + +} // namespace android diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp index 0bbd8a8cf97c..fa8e2e79c831 100644 --- a/libs/hwui/jni/Shader.cpp +++ b/libs/hwui/jni/Shader.cpp @@ -2,11 +2,21 @@ #define LOG_TAG "ShaderJNI" #include "GraphicsJNI.h" +#include "SkBitmap.h" +#include "SkBlendMode.h" +#include "SkColor.h" #include "SkColorFilter.h" #include "SkGradientShader.h" +#include "SkImage.h" #include "SkImagePriv.h" +#include "SkMatrix.h" +#include "SkPoint.h" +#include "SkRefCnt.h" +#include "SkSamplingOptions.h" +#include "SkScalar.h" #include "SkShader.h" -#include "SkBlendMode.h" +#include "SkString.h" +#include "SkTileMode.h" #include "include/effects/SkRuntimeEffect.h" #include <vector> @@ -16,7 +26,7 @@ using namespace android::uirenderer; /** * By default Skia gradients will interpolate their colors in unpremul space * and then premultiply each of the results. We must set this flag to preserve - * backwards compatiblity by premultiplying the colors of the gradient first, + * backwards compatibility by premultiplying the colors of the gradient first, * and then interpolating between them. */ static const uint32_t sGradientShaderFlags = SkGradientShader::kInterpolateColorsInPremul_Flag; diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp index d86d9ee56f4c..209b35c5537c 100644 --- a/libs/hwui/jni/Typeface.cpp +++ b/libs/hwui/jni/Typeface.cpp @@ -20,18 +20,21 @@ #include <minikin/FontCollection.h> #include <minikin/FontFamily.h> #include <minikin/FontFileParser.h> +#include <minikin/LocaleList.h> +#include <minikin/MinikinFontFactory.h> #include <minikin/SystemFonts.h> #include <nativehelper/ScopedPrimitiveArray.h> #include <nativehelper/ScopedUtfChars.h> + +#include <mutex> +#include <unordered_map> + #include "FontUtils.h" #include "GraphicsJNI.h" #include "SkData.h" #include "SkTypeface.h" #include "fonts/Font.h" -#include <mutex> -#include <unordered_map> - #ifdef __ANDROID__ #include <sys/stat.h> #endif @@ -106,27 +109,14 @@ static jint Typeface_getWeight(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) { static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray, jlong fallbackPtr, int weight, int italic) { ScopedLongArrayRO families(env, familyArray); - std::vector<std::shared_ptr<minikin::FontFamily>> familyVec; Typeface* typeface = (fallbackPtr == 0) ? nullptr : toTypeface(fallbackPtr); - if (typeface != nullptr) { - const std::vector<std::shared_ptr<minikin::FontFamily>>& fallbackFamilies = - toTypeface(fallbackPtr)->fFontCollection->getFamilies(); - familyVec.reserve(families.size() + fallbackFamilies.size()); - for (size_t i = 0; i < families.size(); i++) { - FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]); - familyVec.emplace_back(family->family); - } - for (size_t i = 0; i < fallbackFamilies.size(); i++) { - familyVec.emplace_back(fallbackFamilies[i]); - } - } else { - familyVec.reserve(families.size()); - for (size_t i = 0; i < families.size(); i++) { - FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]); - familyVec.emplace_back(family->family); - } + std::vector<std::shared_ptr<minikin::FontFamily>> familyVec; + familyVec.reserve(families.size()); + for (size_t i = 0; i < families.size(); i++) { + FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]); + familyVec.emplace_back(family->family); } - return toJLong(Typeface::createFromFamilies(std::move(familyVec), weight, italic)); + return toJLong(Typeface::createFromFamilies(std::move(familyVec), weight, italic, typeface)); } // CriticalNative @@ -137,15 +127,13 @@ static void Typeface_setDefault(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) { static jobject Typeface_getSupportedAxes(JNIEnv *env, jobject, jlong faceHandle) { Typeface* face = toTypeface(faceHandle); - const std::unordered_set<minikin::AxisTag>& tagSet = face->fFontCollection->getSupportedTags(); - const size_t length = tagSet.size(); + const size_t length = face->fFontCollection->getSupportedAxesCount(); if (length == 0) { return nullptr; } std::vector<jint> tagVec(length); - int index = 0; - for (const auto& tag : tagSet) { - tagVec[index++] = tag; + for (size_t i = 0; i < length; i++) { + tagVec[i] = face->fFontCollection->getSupportedAxisAt(i); } std::sort(tagVec.begin(), tagVec.end()); const jintArray result = env->NewIntArray(length); @@ -204,9 +192,18 @@ static sk_sp<SkData> makeSkDataCached(const std::string& path, bool hasVerity) { return entry; } -static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader); +class MinikinFontSkiaFactory : minikin::MinikinFontFactory { +private: + MinikinFontSkiaFactory() : MinikinFontFactory() { MinikinFontFactory::setInstance(this); } + +public: + static void init() { static MinikinFontSkiaFactory factory; } + void skip(minikin::BufferReader* reader) const override; + std::shared_ptr<minikin::MinikinFont> create(minikin::BufferReader reader) const override; + void write(minikin::BufferWriter* writer, const minikin::MinikinFont* typeface) const override; +}; -static minikin::Font::TypefaceLoader* readMinikinFontSkia(minikin::BufferReader* reader) { +void MinikinFontSkiaFactory::skip(minikin::BufferReader* reader) const { // Advance reader's position. reader->skipString(); // fontPath reader->skip<int>(); // fontIndex @@ -216,10 +213,10 @@ static minikin::Font::TypefaceLoader* readMinikinFontSkia(minikin::BufferReader* reader->skip<uint32_t>(); // expectedFontRevision reader->skipString(); // expectedPostScriptName } - return &loadMinikinFontSkia; } -static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader reader) { +std::shared_ptr<minikin::MinikinFont> MinikinFontSkiaFactory::create( + minikin::BufferReader reader) const { std::string_view fontPath = reader.readString(); std::string path(fontPath.data(), fontPath.size()); ATRACE_FORMAT("Loading font %s", path.c_str()); @@ -268,8 +265,8 @@ static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::Buffer return minikinFont; } -static void writeMinikinFontSkia(minikin::BufferWriter* writer, - const minikin::MinikinFont* typeface) { +void MinikinFontSkiaFactory::write(minikin::BufferWriter* writer, + const minikin::MinikinFont* typeface) const { // When you change the format of font metadata, please update code to parse // typefaceMetadataReader() in // frameworks/base/libs/hwui/jni/fonts/Font.cpp too. @@ -293,7 +290,9 @@ static void writeMinikinFontSkia(minikin::BufferWriter* writer, } } -static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongArray faceHandles) { +static jint Typeface_writeTypefaces(JNIEnv* env, jobject, jobject buffer, jint position, + jlongArray faceHandles) { + MinikinFontSkiaFactory::init(); ScopedLongArrayRO faces(env, faceHandles); std::vector<Typeface*> typefaces; typefaces.reserve(faces.size()); @@ -301,7 +300,12 @@ static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongA typefaces.push_back(toTypeface(faces[i])); } void* addr = buffer == nullptr ? nullptr : env->GetDirectBufferAddress(buffer); - minikin::BufferWriter writer(addr); + if (addr != nullptr && + reinterpret_cast<intptr_t>(addr) % minikin::BufferReader::kMaxAlignment != 0) { + ALOGE("addr (%p) must be aligned at kMaxAlignment, but it was not.", addr); + return 0; + } + minikin::BufferWriter writer(addr, position); std::vector<std::shared_ptr<minikin::FontCollection>> fontCollections; std::unordered_map<std::shared_ptr<minikin::FontCollection>, size_t> fcToIndex; for (Typeface* typeface : typefaces) { @@ -310,7 +314,7 @@ static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongA fontCollections.push_back(typeface->fFontCollection); } } - minikin::FontCollection::writeVector<writeMinikinFontSkia>(&writer, fontCollections); + minikin::FontCollection::writeVector(&writer, fontCollections); writer.write<uint32_t>(typefaces.size()); for (Typeface* typeface : typefaces) { writer.write<uint32_t>(fcToIndex.find(typeface->fFontCollection)->second); @@ -321,12 +325,20 @@ static jint Typeface_writeTypefaces(JNIEnv *env, jobject, jobject buffer, jlongA return static_cast<jint>(writer.size()); } -static jlongArray Typeface_readTypefaces(JNIEnv *env, jobject, jobject buffer) { +static jlongArray Typeface_readTypefaces(JNIEnv* env, jobject, jobject buffer, jint position) { + MinikinFontSkiaFactory::init(); void* addr = buffer == nullptr ? nullptr : env->GetDirectBufferAddress(buffer); - if (addr == nullptr) return nullptr; - minikin::BufferReader reader(addr); + if (addr == nullptr) { + ALOGE("Passed a null buffer."); + return nullptr; + } + if (reinterpret_cast<intptr_t>(addr) % minikin::BufferReader::kMaxAlignment != 0) { + ALOGE("addr (%p) must be aligned at kMaxAlignment, but it was not.", addr); + return nullptr; + } + minikin::BufferReader reader(addr, position); std::vector<std::shared_ptr<minikin::FontCollection>> fontCollections = - minikin::FontCollection::readVector<readMinikinFontSkia>(&reader); + minikin::FontCollection::readVector(&reader); uint32_t typefaceCount = reader.read<uint32_t>(); std::vector<jlong> faceHandles; faceHandles.reserve(typefaceCount); @@ -343,7 +355,6 @@ static jlongArray Typeface_readTypefaces(JNIEnv *env, jobject, jobject buffer) { return result; } - static void Typeface_forceSetStaticFinalField(JNIEnv *env, jclass cls, jstring fieldName, jobject typeface) { ScopedUtfChars fieldNameChars(env, fieldName); @@ -356,18 +367,6 @@ static void Typeface_forceSetStaticFinalField(JNIEnv *env, jclass cls, jstring f env->SetStaticObjectField(cls, fid, typeface); } -// Critical Native -static jint Typeface_getFamilySize(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) { - return toTypeface(faceHandle)->fFontCollection->getFamilies().size(); -} - -// Critical Native -static jlong Typeface_getFamily(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle, jint index) { - std::shared_ptr<minikin::FontFamily> family = - toTypeface(faceHandle)->fFontCollection->getFamilies()[index]; - return reinterpret_cast<jlong>(new FontFamilyWrapper(std::move(family))); -} - // Regular JNI static void Typeface_warmUpCache(JNIEnv* env, jobject, jstring jFilePath) { ScopedUtfChars filePath(env, jFilePath); @@ -380,6 +379,12 @@ static void Typeface_addFontCollection(CRITICAL_JNI_PARAMS_COMMA jlong faceHandl minikin::SystemFonts::addFontMap(std::move(collection)); } +// Fast Native +static void Typeface_registerLocaleList(JNIEnv* env, jobject, jstring jLocales) { + ScopedUtfChars locales(env, jLocales); + minikin::registerLocaleList(locales.c_str()); +} + /////////////////////////////////////////////////////////////////////////////// static const JNINativeMethod gTypefaceMethods[] = { @@ -397,14 +402,13 @@ static const JNINativeMethod gTypefaceMethods[] = { {"nativeGetSupportedAxes", "(J)[I", (void*)Typeface_getSupportedAxes}, {"nativeRegisterGenericFamily", "(Ljava/lang/String;J)V", (void*)Typeface_registerGenericFamily}, - {"nativeWriteTypefaces", "(Ljava/nio/ByteBuffer;[J)I", (void*)Typeface_writeTypefaces}, - {"nativeReadTypefaces", "(Ljava/nio/ByteBuffer;)[J", (void*)Typeface_readTypefaces}, + {"nativeWriteTypefaces", "(Ljava/nio/ByteBuffer;I[J)I", (void*)Typeface_writeTypefaces}, + {"nativeReadTypefaces", "(Ljava/nio/ByteBuffer;I)[J", (void*)Typeface_readTypefaces}, {"nativeForceSetStaticFinalField", "(Ljava/lang/String;Landroid/graphics/Typeface;)V", (void*)Typeface_forceSetStaticFinalField}, - {"nativeGetFamilySize", "(J)I", (void*)Typeface_getFamilySize}, - {"nativeGetFamily", "(JI)J", (void*)Typeface_getFamily}, {"nativeWarmUpCache", "(Ljava/lang/String;)V", (void*)Typeface_warmUpCache}, {"nativeAddFontCollections", "(J)V", (void*)Typeface_addFontCollection}, + {"nativeRegisterLocaleList", "(Ljava/lang/String;)V", (void*)Typeface_registerLocaleList}, }; int register_android_graphics_Typeface(JNIEnv* env) diff --git a/libs/hwui/jni/Utils.h b/libs/hwui/jni/Utils.h index 6cdf44d85a5a..f6e3a0eeaa0e 100644 --- a/libs/hwui/jni/Utils.h +++ b/libs/hwui/jni/Utils.h @@ -17,8 +17,11 @@ #ifndef _ANDROID_GRAPHICS_UTILS_H_ #define _ANDROID_GRAPHICS_UTILS_H_ +#include "SkRefCnt.h" #include "SkStream.h" +class SkData; + #include <jni.h> #include <androidfw/Asset.h> diff --git a/libs/hwui/jni/YuvToJpegEncoder.cpp b/libs/hwui/jni/YuvToJpegEncoder.cpp index d64d38a815f6..1c5f126d8672 100644 --- a/libs/hwui/jni/YuvToJpegEncoder.cpp +++ b/libs/hwui/jni/YuvToJpegEncoder.cpp @@ -1,5 +1,7 @@ #include "CreateJavaOutputStreamAdaptor.h" #include "SkJPEGWriteUtility.h" +#include "SkStream.h" +#include "SkTypes.h" #include "YuvToJpegEncoder.h" #include <ui/PixelFormat.h> #include <hardware/hardware.h> diff --git a/libs/hwui/jni/YuvToJpegEncoder.h b/libs/hwui/jni/YuvToJpegEncoder.h index 7e7b935df276..a69726b17e9d 100644 --- a/libs/hwui/jni/YuvToJpegEncoder.h +++ b/libs/hwui/jni/YuvToJpegEncoder.h @@ -1,13 +1,13 @@ #ifndef _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_ #define _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_ -#include "SkTypes.h" -#include "SkStream.h" extern "C" { #include "jpeglib.h" #include "jerror.h" } +class SkWStream; + class YuvToJpegEncoder { public: /** Create an encoder based on the YUV format. diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp index 132234b38003..0513447ed05e 100644 --- a/libs/hwui/jni/android_graphics_Canvas.cpp +++ b/libs/hwui/jni/android_graphics_Canvas.cpp @@ -32,10 +32,22 @@ #include "FontUtils.h" #include "Bitmap.h" +#include "SkBitmap.h" +#include "SkBlendMode.h" +#include "SkClipOp.h" +#include "SkColor.h" +#include "SkColorSpace.h" #include "SkGraphics.h" +#include "SkImageInfo.h" +#include "SkMatrix.h" +#include "SkPath.h" +#include "SkPoint.h" +#include "SkRect.h" +#include "SkRefCnt.h" #include "SkRegion.h" -#include "SkVertices.h" #include "SkRRect.h" +#include "SkScalar.h" +#include "SkVertices.h" namespace minikin { class MeasuredText; @@ -701,9 +713,10 @@ static void setCompatibilityVersion(JNIEnv* env, jobject, jint apiLevel) { } static void punchHole(JNIEnv* env, jobject, jlong canvasPtr, jfloat left, jfloat top, jfloat right, - jfloat bottom, jfloat rx, jfloat ry) { + jfloat bottom, jfloat rx, jfloat ry, jfloat alpha) { auto canvas = reinterpret_cast<Canvas*>(canvasPtr); - canvas->punchHole(SkRRect::MakeRectXY(SkRect::MakeLTRB(left, top, right, bottom), rx, ry)); + canvas->punchHole(SkRRect::MakeRectXY(SkRect::MakeLTRB(left, top, right, bottom), rx, ry), + alpha); } }; // namespace CanvasJNI @@ -778,7 +791,7 @@ static const JNINativeMethod gDrawMethods[] = { {"nDrawTextRun","(JLjava/lang/String;IIIIFFZJ)V", (void*) CanvasJNI::drawTextRunString}, {"nDrawTextOnPath","(J[CIIJFFIJ)V", (void*) CanvasJNI::drawTextOnPathChars}, {"nDrawTextOnPath","(JLjava/lang/String;JFFIJ)V", (void*) CanvasJNI::drawTextOnPathString}, - {"nPunchHole", "(JFFFFFF)V", (void*) CanvasJNI::punchHole} + {"nPunchHole", "(JFFFFFFF)V", (void*) CanvasJNI::punchHole} }; int register_android_graphics_Canvas(JNIEnv* env) { diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index c48448dffdd2..4f281fcde61d 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -23,8 +23,16 @@ #include <Picture.h> #include <Properties.h> #include <RootRenderNode.h> +#include <SkBitmap.h> +#include <SkColorSpace.h> +#include <SkData.h> +#include <SkImage.h> #include <SkImagePriv.h> +#include <SkPicture.h> +#include <SkPixmap.h> #include <SkSerialProcs.h> +#include <SkStream.h> +#include <SkTypeface.h> #include <dlfcn.h> #include <gui/TraceUtils.h> #include <inttypes.h> @@ -80,6 +88,11 @@ struct { jmethodID onFrameComplete; } gFrameCompleteCallback; +struct { + jmethodID onCopyFinished; + jmethodID getDestinationBitmap; +} gCopyRequest; + static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { @@ -451,7 +464,7 @@ struct PictureCaptureState { }; // TODO: This & Multi-SKP & Single-SKP should all be de-duped into -// a single "make a SkPicture serailizable-safe" utility somewhere +// a single "make a SkPicture serializable-safe" utility somewhere class PictureWrapper : public Picture { public: PictureWrapper(sk_sp<SkPicture>&& src, const std::shared_ptr<PictureCaptureState>& state) @@ -664,15 +677,41 @@ static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env, } } -static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, - jobject clazz, jobject jsurface, jint left, jint top, - jint right, jint bottom, jlong bitmapPtr) { - SkBitmap bitmap; - bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap); +class CopyRequestAdapter : public CopyRequest { +public: + CopyRequestAdapter(JavaVM* vm, jobject jCopyRequest, Rect srcRect) + : CopyRequest(srcRect), mRefHolder(vm, jCopyRequest) {} + + virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) override { + JNIEnv* env = getenv(mRefHolder.vm()); + jlong bitmapPtr = env->CallLongMethod( + mRefHolder.object(), gCopyRequest.getDestinationBitmap, srcWidth, srcHeight); + SkBitmap bitmap; + bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap); + return bitmap; + } + + virtual void onCopyFinished(CopyResult result) override { + JNIEnv* env = getenv(mRefHolder.vm()); + env->CallVoidMethod(mRefHolder.object(), gCopyRequest.onCopyFinished, + static_cast<jint>(result)); + } + +private: + JGlobalRefHolder mRefHolder; +}; + +static void android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, jobject clazz, + jobject jsurface, jint left, jint top, + jint right, jint bottom, + jobject jCopyRequest) { + JavaVM* vm = nullptr; + LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); + auto copyRequest = std::make_shared<CopyRequestAdapter>(vm, env->NewGlobalRef(jCopyRequest), + Rect(left, top, right, bottom)); ANativeWindow* window = fromSurface(env, jsurface); - jint result = RenderProxy::copySurfaceInto(window, left, top, right, bottom, &bitmap); + RenderProxy::copySurfaceInto(window, std::move(copyRequest)); ANativeWindow_release(window); - return result; } class ContextFactory : public IContextFactory { @@ -961,7 +1000,8 @@ static const JNINativeMethod gMethods[] = { (void*)android_view_ThreadedRenderer_setFrameCompleteCallback}, {"nAddObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_addObserver}, {"nRemoveObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_removeObserver}, - {"nCopySurfaceInto", "(Landroid/view/Surface;IIIIJ)I", + {"nCopySurfaceInto", + "(Landroid/view/Surface;IIIILandroid/graphics/HardwareRenderer$CopyRequest;)V", (void*)android_view_ThreadedRenderer_copySurfaceInto}, {"nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;", (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode}, @@ -1034,6 +1074,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) { gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass, "onFrameComplete", "()V"); + jclass copyRequest = FindClassOrDie(env, "android/graphics/HardwareRenderer$CopyRequest"); + gCopyRequest.onCopyFinished = GetMethodIDOrDie(env, copyRequest, "onCopyFinished", "(I)V"); + gCopyRequest.getDestinationBitmap = + GetMethodIDOrDie(env, copyRequest, "getDestinationBitmap", "(II)J"); + void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE); fromSurface = (ANW_fromSurface)dlsym(handle_, "ANativeWindow_fromSurface"); LOG_ALWAYS_FATAL_IF(fromSurface == nullptr, diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp index 09be630dc741..f17129c8d953 100644 --- a/libs/hwui/jni/fonts/Font.cpp +++ b/libs/hwui/jni/fonts/Font.cpp @@ -22,7 +22,10 @@ #include "SkFont.h" #include "SkFontMetrics.h" #include "SkFontMgr.h" +#include "SkRect.h" #include "SkRefCnt.h" +#include "SkScalar.h" +#include "SkStream.h" #include "SkTypeface.h" #include "GraphicsJNI.h" #include <nativehelper/ScopedUtfChars.h> @@ -225,7 +228,7 @@ static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) { static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); minikin::BufferReader reader = font->font->typefaceMetadataReader(); - if (reader.data() != nullptr) { + if (reader.current() != nullptr) { std::string path = std::string(reader.readString()); if (path.empty()) { return nullptr; @@ -267,7 +270,7 @@ static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); minikin::BufferReader reader = font->font->typefaceMetadataReader(); - if (reader.data() != nullptr) { + if (reader.current() != nullptr) { reader.skipString(); // fontPath return reader.read<int>(); } else { @@ -280,7 +283,7 @@ static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); minikin::BufferReader reader = font->font->typefaceMetadataReader(); - if (reader.data() != nullptr) { + if (reader.current() != nullptr) { reader.skipString(); // fontPath reader.skip<int>(); // fontIndex return reader.readArray<minikin::FontVariation>().second; @@ -295,7 +298,7 @@ static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint inde FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); minikin::BufferReader reader = font->font->typefaceMetadataReader(); minikin::FontVariation var; - if (reader.data() != nullptr) { + if (reader.current() != nullptr) { reader.skipString(); // fontPath reader.skip<int>(); // fontIndex var = reader.readArray<minikin::FontVariation>().first[index]; diff --git a/libs/hwui/jni/fonts/FontFamily.cpp b/libs/hwui/jni/fonts/FontFamily.cpp index b68213549938..fbfc07e1f89d 100644 --- a/libs/hwui/jni/fonts/FontFamily.cpp +++ b/libs/hwui/jni/fonts/FontFamily.cpp @@ -66,9 +66,9 @@ static jlong FontFamily_Builder_build(JNIEnv* env, jobject clazz, jlong builderP ScopedUtfChars str(env, langTags); localeId = minikin::registerLocaleList(str.c_str()); } - std::shared_ptr<minikin::FontFamily> family = std::make_shared<minikin::FontFamily>( - localeId, static_cast<minikin::FamilyVariant>(variant), std::move(builder->fonts), - isCustomFallback); + std::shared_ptr<minikin::FontFamily> family = + minikin::FontFamily::create(localeId, static_cast<minikin::FamilyVariant>(variant), + std::move(builder->fonts), isCustomFallback); if (family->getCoverage().length() == 0) { // No coverage means minikin rejected given font for some reasons. jniThrowException(env, "java/lang/IllegalArgumentException", diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h index 3f89c0712407..6a052dbb7cea 100644 --- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h +++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h @@ -19,6 +19,8 @@ #include "RenderNode.h" #include "SkiaDisplayList.h" +class SkRRect; + namespace android { namespace uirenderer { namespace skiapipeline { diff --git a/libs/hwui/pipeline/skia/HolePunch.h b/libs/hwui/pipeline/skia/HolePunch.h index 92c6f7721a08..d0e1ca35049a 100644 --- a/libs/hwui/pipeline/skia/HolePunch.h +++ b/libs/hwui/pipeline/skia/HolePunch.h @@ -17,7 +17,6 @@ #pragma once #include <string> -#include "SkRRect.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp index 507d3dcdcde9..f2282e661535 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp @@ -15,7 +15,11 @@ */ #include "RenderNodeDrawable.h" +#include <SkPaint.h> #include <SkPaintFilterCanvas.h> +#include <SkPoint.h> +#include <SkRRect.h> +#include <SkRect.h> #include <gui/TraceUtils.h> #include "RenderNode.h" #include "SkiaDisplayList.h" @@ -197,6 +201,7 @@ protected: paint.setAlpha((uint8_t)paint.getAlpha() * mAlpha); return true; } + void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override { // We unroll the drawable using "this" canvas, so that draw calls contained inside will // get their alpha applied. The default SkPaintFilterCanvas::onDrawDrawable does not unroll. @@ -288,7 +293,7 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const { // with the same canvas transformation + clip into the target // canvas then draw the layer on top if (renderNode->hasHolePunches()) { - TransformCanvas transformCanvas(canvas, SkBlendMode::kClear); + TransformCanvas transformCanvas(canvas, SkBlendMode::kDstOut); displayList->draw(&transformCanvas); } canvas->drawImageRect(snapshotImage, SkRect::Make(srcBounds), diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp index 7cfccb56382c..11977bd54c2c 100644 --- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp +++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp @@ -19,8 +19,15 @@ #include "SkiaDisplayList.h" #include "LightingInfo.h" +#include <SkColor.h> +#include <SkMatrix.h> +#include <SkPath.h> #include <SkPathOps.h> +#include <SkPoint3.h> +#include <SkRect.h> +#include <SkScalar.h> #include <SkShadowUtils.h> +#include <include/private/SkShadowFlags.h> namespace android { namespace uirenderer { diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp index 90c4440c8339..a55de95035a7 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.cpp +++ b/libs/hwui/pipeline/skia/ShaderCache.cpp @@ -16,6 +16,7 @@ #include "ShaderCache.h" #include <GrDirectContext.h> +#include <SkData.h> #include <gui/TraceUtils.h> #include <log/log.h> #include <openssl/sha.h> diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h index 3e0fd5164011..bc35fa5f9987 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.h +++ b/libs/hwui/pipeline/skia/ShaderCache.h @@ -17,12 +17,15 @@ #pragma once #include <GrContextOptions.h> +#include <SkRefCnt.h> #include <cutils/compiler.h> #include <memory> #include <mutex> #include <string> #include <vector> +class SkData; + namespace android { class BlobCache; @@ -45,7 +48,7 @@ public: * and puts the ShaderCache into an initialized state, such that it is * able to insert and retrieve entries from the cache. If identity is * non-null and validation fails, the cache is initialized but contains - * no data. If size is less than zero, the cache is initilaized but + * no data. If size is less than zero, the cache is initialized but * contains no data. * * This should be called when HWUI pipeline is initialized. When not in diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index 2aca41e41905..19cd7bdd6fcb 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -53,8 +53,12 @@ SkiaOpenGLPipeline::~SkiaOpenGLPipeline() { } MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() { - // TODO: Figure out why this workaround is needed, see b/13913604 - // In the meantime this matches the behavior of GLRenderer, so it is not a regression + // In case the surface was destroyed (e.g. a previous trimMemory call) we + // need to recreate it here. + if (!isSurfaceReady() && mNativeWindow) { + setSurface(mNativeWindow.get(), mSwapBehavior); + } + EGLint error = 0; if (!mEglManager.makeCurrent(mEglSurface, &error)) { return MakeCurrentResult::AlreadyCurrent; @@ -112,7 +116,7 @@ IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw( if (CC_UNLIKELY(Properties::showDirtyRegions || ProfileType::None != Properties::getProfileType())) { SkCanvas* profileCanvas = surface->getCanvas(); - SkiaProfileRenderer profileRenderer(profileCanvas); + SkiaProfileRenderer profileRenderer(profileCanvas, frame.width(), frame.height()); profiler->draw(profileRenderer); } @@ -166,6 +170,9 @@ void SkiaOpenGLPipeline::onStop() { } bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) { + mNativeWindow = surface; + mSwapBehavior = swapBehavior; + if (mEglSurface != EGL_NO_SURFACE) { mEglManager.destroySurface(mEglSurface); mEglSurface = EGL_NO_SURFACE; @@ -182,7 +189,8 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh if (mEglSurface != EGL_NO_SURFACE) { const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); - mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); + const bool isPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); + ALOGE_IF(preserveBuffer != isPreserved, "Unable to match the desired swap behavior."); return true; } diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h index 186998a01745..a80c613697f2 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h @@ -61,7 +61,8 @@ protected: private: renderthread::EglManager& mEglManager; EGLSurface mEglSurface = EGL_NO_SURFACE; - bool mBufferPreserved = false; + sp<ANativeWindow> mNativeWindow; + renderthread::SwapBehavior mSwapBehavior = renderthread::SwapBehavior::kSwap_discardBuffer; }; } /* namespace skiapipeline */ diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index bc386feb2d6f..c546adaaf779 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -16,15 +16,25 @@ #include "SkiaPipeline.h" +#include <SkCanvas.h> +#include <SkColor.h> +#include <SkColorSpace.h> +#include <SkData.h> +#include <SkImage.h> #include <SkImageEncoder.h> #include <SkImageInfo.h> #include <SkImagePriv.h> +#include <SkMatrix.h> #include <SkMultiPictureDocument.h> #include <SkOverdrawCanvas.h> #include <SkOverdrawColorFilter.h> #include <SkPicture.h> #include <SkPictureRecorder.h> +#include <SkRect.h> +#include <SkRefCnt.h> #include <SkSerialProcs.h> +#include <SkStream.h> +#include <SkString.h> #include <SkTypeface.h> #include <android-base/properties.h> #include <unistd.h> diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index bc8a5659dd83..7887d1ae2117 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -16,14 +16,16 @@ #pragma once -#include <SkSurface.h> +#include <SkColorSpace.h> #include <SkDocument.h> #include <SkMultiPictureDocument.h> +#include <SkSurface.h> #include "Lighting.h" #include "hwui/AnimatedImageDrawable.h" #include "renderthread/CanvasContext.h" #include "renderthread/IRenderPipeline.h" +class SkFILEWStream; class SkPictureRecorder; struct SkSharingSerialContext; diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp b/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp index 492c39f1288c..81cfc5d93419 100644 --- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp +++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp @@ -33,13 +33,5 @@ void SkiaProfileRenderer::drawRects(const float* rects, int count, const SkPaint } } -uint32_t SkiaProfileRenderer::getViewportWidth() { - return mCanvas->imageInfo().width(); -} - -uint32_t SkiaProfileRenderer::getViewportHeight() { - return mCanvas->imageInfo().height(); -} - } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h index dc8420f4e01b..96d2a5e58139 100644 --- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h +++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h @@ -23,18 +23,21 @@ namespace uirenderer { class SkiaProfileRenderer : public IProfileRenderer { public: - explicit SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {} + explicit SkiaProfileRenderer(SkCanvas* canvas, uint32_t width, uint32_t height) + : mCanvas(canvas), mWidth(width), mHeight(height) {} void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override; void drawRects(const float* rects, int count, const SkPaint& paint) override; - uint32_t getViewportWidth() override; - uint32_t getViewportHeight() override; + uint32_t getViewportWidth() override { return mWidth; } + uint32_t getViewportHeight() override { return mHeight; } virtual ~SkiaProfileRenderer() {} private: // Does not have ownership. SkCanvas* mCanvas; + uint32_t mWidth; + uint32_t mHeight; }; } /* namespace uirenderer */ diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index 9c51e628e04a..1f87865f2672 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -16,7 +16,20 @@ #include "SkiaRecordingCanvas.h" #include "hwui/Paint.h" +#include <include/private/SkTemplates.h> // SkAutoSTMalloc +#include <SkBlendMode.h> +#include <SkData.h> +#include <SkDrawable.h> +#include <SkImage.h> #include <SkImagePriv.h> +#include <SkMatrix.h> +#include <SkPaint.h> +#include <SkPoint.h> +#include <SkRect.h> +#include <SkRefCnt.h> +#include <SkRRect.h> +#include <SkSamplingOptions.h> +#include <SkTypes.h> #include "CanvasTransform.h" #ifdef __ANDROID__ // Layoutlib does not support Layers #include "Layer.h" @@ -56,20 +69,22 @@ void SkiaRecordingCanvas::initDisplayList(uirenderer::RenderNode* renderNode, in mDisplayList->setHasHolePunches(false); } -void SkiaRecordingCanvas::punchHole(const SkRRect& rect) { - // Add the marker annotation to allow HWUI to determine where the current - // clip/transformation should be applied +void SkiaRecordingCanvas::punchHole(const SkRRect& rect, float alpha) { + // Add the marker annotation to allow HWUI to determine the current + // clip/transformation and alpha should be applied SkVector vector = rect.getSimpleRadii(); - float data[2]; + float data[3]; data[0] = vector.x(); data[1] = vector.y(); + data[2] = alpha; mRecorder.drawAnnotation(rect.rect(), HOLE_PUNCH_ANNOTATION.c_str(), - SkData::MakeWithCopy(data, 2 * sizeof(float))); + SkData::MakeWithCopy(data, sizeof(data))); // Clear the current rect within the layer itself SkPaint paint = SkPaint(); - paint.setColor(0); - paint.setBlendMode(SkBlendMode::kClear); + paint.setColor(SkColors::kBlack); + paint.setAlphaf(alpha); + paint.setBlendMode(SkBlendMode::kDstOut); mRecorder.drawRRect(rect, paint); mDisplayList->setHasHolePunches(true); diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h index 1445a27e4248..7844e2cc2a73 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -22,6 +22,11 @@ #include "SkiaDisplayList.h" #include "pipeline/skia/AnimatedDrawables.h" +class SkBitmap; +class SkMatrix; +class SkPaint; +class SkRRect; + namespace android { namespace uirenderer { namespace skiapipeline { @@ -45,7 +50,7 @@ public: initDisplayList(renderNode, width, height); } - virtual void punchHole(const SkRRect& rect) override; + virtual void punchHole(const SkRRect& rect, float alpha) override; virtual void finishRecording(uirenderer::RenderNode* destination) override; std::unique_ptr<SkiaDisplayList> finishRecording(); diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 905d46e58014..f10bca675bf7 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -55,7 +55,12 @@ VulkanManager& SkiaVulkanPipeline::vulkanManager() { } MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { - return MakeCurrentResult::AlreadyCurrent; + // In case the surface was destroyed (e.g. a previous trimMemory call) we + // need to recreate it here. + if (!isSurfaceReady() && mNativeWindow) { + setSurface(mNativeWindow.get(), SwapBehavior::kSwap_default); + } + return isContextReady() ? MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed; } Frame SkiaVulkanPipeline::getFrame() { @@ -88,7 +93,9 @@ IRenderPipeline::DrawResult SkiaVulkanPipeline::draw( if (CC_UNLIKELY(Properties::showDirtyRegions || ProfileType::None != Properties::getProfileType())) { SkCanvas* profileCanvas = backBuffer->getCanvas(); - SkiaProfileRenderer profileRenderer(profileCanvas); + SkAutoCanvasRestore saver(profileCanvas, true); + profileCanvas->concat(mVkSurface->getCurrentPreTransform()); + SkiaProfileRenderer profileRenderer(profileCanvas, frame.width(), frame.height()); profiler->draw(profileRenderer); } @@ -130,7 +137,11 @@ DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() { void SkiaVulkanPipeline::onStop() {} -bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) { +// We can safely ignore the swap behavior because VkManager will always operate +// in a mode equivalent to EGLManager::SwapBehavior::kBufferAge +bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior /*swapBehavior*/) { + mNativeWindow = surface; + if (mVkSurface) { vulkanManager().destroySurface(mVkSurface); mVkSurface = nullptr; diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index ada6af67d4a0..f3d36131a22f 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -22,6 +22,11 @@ #include "renderstate/RenderState.h" +#include "SkRefCnt.h" + +class SkBitmap; +struct SkRect; + namespace android { namespace uirenderer { namespace skiapipeline { @@ -61,6 +66,7 @@ private: renderthread::VulkanManager& vulkanManager(); renderthread::VulkanSurface* mVkSurface = nullptr; + sp<ANativeWindow> mNativeWindow; }; } /* namespace skiapipeline */ diff --git a/libs/hwui/pipeline/skia/TransformCanvas.cpp b/libs/hwui/pipeline/skia/TransformCanvas.cpp index 41e36874b862..c320df035d08 100644 --- a/libs/hwui/pipeline/skia/TransformCanvas.cpp +++ b/libs/hwui/pipeline/skia/TransformCanvas.cpp @@ -19,19 +19,25 @@ #include "HolePunch.h" #include "SkData.h" #include "SkDrawable.h" +#include "SkMatrix.h" +#include "SkPaint.h" +#include "SkRect.h" +#include "SkRRect.h" using namespace android::uirenderer::skiapipeline; void TransformCanvas::onDrawAnnotation(const SkRect& rect, const char* key, SkData* value) { if (HOLE_PUNCH_ANNOTATION == key) { auto* rectParams = reinterpret_cast<const float*>(value->data()); - float radiusX = rectParams[0]; - float radiusY = rectParams[1]; + const float radiusX = rectParams[0]; + const float radiusY = rectParams[1]; + const float alpha = rectParams[2]; SkRRect roundRect = SkRRect::MakeRectXY(rect, radiusX, radiusY); SkPaint paint; paint.setColor(SkColors::kBlack); paint.setBlendMode(mHolePunchBlendMode); + paint.setAlphaf(alpha); mWrappedCanvas->drawRRect(roundRect, paint); } } diff --git a/libs/hwui/pipeline/skia/TransformCanvas.h b/libs/hwui/pipeline/skia/TransformCanvas.h index 685b71d017e9..15f0c1abc55a 100644 --- a/libs/hwui/pipeline/skia/TransformCanvas.h +++ b/libs/hwui/pipeline/skia/TransformCanvas.h @@ -19,6 +19,13 @@ #include "SkPaintFilterCanvas.h" #include <effects/StretchEffect.h> +class SkData; +class SkDrawable; +class SkMatrix; +class SkPaint; +enum class SkBlendMode; +struct SkRect; + class TransformCanvas : public SkPaintFilterCanvas { public: TransformCanvas(SkCanvas* target, SkBlendMode blendmode) : diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h index fc6b28d2e1ad..b8f8c9267ad8 100644 --- a/libs/hwui/renderthread/EglManager.h +++ b/libs/hwui/renderthread/EglManager.h @@ -18,6 +18,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> +#include <SkColorSpace.h> #include <SkImageInfo.h> #include <SkRect.h> #include <cutils/compiler.h> diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h index ef58bc553c23..35e370f52fda 100644 --- a/libs/hwui/renderthread/IRenderPipeline.h +++ b/libs/hwui/renderthread/IRenderPipeline.h @@ -24,6 +24,7 @@ #include "hwui/Bitmap.h" #include "ColorMode.h" +#include <SkColorSpace.h> #include <SkRect.h> #include <utils/RefBase.h> diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index a44b498c81c1..40a0bac3762d 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -29,6 +29,10 @@ #include "utils/Macros.h" #include "utils/TimeUtils.h" +#include <SkBitmap.h> +#include <SkImage.h> +#include <SkPicture.h> + #include <pthread.h> namespace android { @@ -360,12 +364,13 @@ void RenderProxy::setForceDark(bool enable) { mRenderThread.queue().post([this, enable]() { mContext->setForceDark(enable); }); } -int RenderProxy::copySurfaceInto(ANativeWindow* window, int left, int top, int right, int bottom, - SkBitmap* bitmap) { +void RenderProxy::copySurfaceInto(ANativeWindow* window, std::shared_ptr<CopyRequest>&& request) { auto& thread = RenderThread::getInstance(); - return static_cast<int>(thread.queue().runSync([&]() -> auto { - return thread.readback().copySurfaceInto(window, Rect(left, top, right, bottom), bitmap); - })); + ANativeWindow_acquire(window); + thread.queue().post([&thread, window, request = std::move(request)] { + thread.readback().copySurfaceInto(window, request); + ANativeWindow_release(window); + }); } void RenderProxy::prepareToDraw(Bitmap& bitmap) { diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index ee9efd46e307..2a99a736180f 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -17,19 +17,24 @@ #ifndef RENDERPROXY_H_ #define RENDERPROXY_H_ -#include <SkBitmap.h> +#include <SkRefCnt.h> #include <android/native_window.h> -#include <cutils/compiler.h> #include <android/surface_control.h> +#include <cutils/compiler.h> #include <utils/Functor.h> #include "../FrameMetricsObserver.h" #include "../IContextFactory.h" #include "ColorMode.h" +#include "CopyRequest.h" #include "DrawFrameTask.h" #include "SwapBehavior.h" #include "hwui/Bitmap.h" +class SkBitmap; +class SkPicture; +class SkImage; + namespace android { class GraphicBuffer; class Surface; @@ -133,8 +138,7 @@ public: void removeFrameMetricsObserver(FrameMetricsObserver* observer); void setForceDark(bool enable); - static int copySurfaceInto(ANativeWindow* window, int left, int top, int right, - int bottom, SkBitmap* bitmap); + static void copySurfaceInto(ANativeWindow* window, std::shared_ptr<CopyRequest>&& request); static void prepareToDraw(Bitmap& bitmap); static int copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap); diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 01b956cb3dd5..3ff4081726f3 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -266,7 +266,7 @@ void RenderThread::requireGlContext() { } mEglManager->initialize(); - sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface()); + sk_sp<const GrGLInterface> glInterface = GrGLMakeNativeInterface(); LOG_ALWAYS_FATAL_IF(!glInterface.get()); GrContextOptions options; diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index b8c2bdf112f8..c5196eeccea3 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -51,7 +51,8 @@ typedef void(VKAPI_PTR* PFN_vkFrameBoundaryANDROID)(VkDevice device, VkSemaphore #include "VulkanSurface.h" #include "private/hwui/DrawVkInfo.h" -class GrVkExtensions; +#include <SkColorSpace.h> +#include <SkRefCnt.h> namespace android { namespace uirenderer { diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h index beb71b727f51..26486669e712 100644 --- a/libs/hwui/renderthread/VulkanSurface.h +++ b/libs/hwui/renderthread/VulkanSurface.h @@ -20,6 +20,7 @@ #include <system/window.h> #include <vulkan/vulkan.h> +#include <SkColorSpace.h> #include <SkRefCnt.h> #include <SkSize.h> diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index 491af4336f97..a4890ede8faa 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -26,7 +26,13 @@ #include <renderthread/VulkanManager.h> #include <utils/Unicode.h> +#include "SkCanvas.h" #include "SkColorData.h" +#include "SkMatrix.h" +#include "SkPath.h" +#include "SkPixmap.h" +#include "SkRect.h" +#include "SkSurface.h" #include "SkUnPreMultiply.h" namespace android { diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index 5092675a8104..75865c751d52 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -27,10 +27,20 @@ #include <renderstate/RenderState.h> #include <renderthread/RenderThread.h> +#include <SkBitmap.h> +#include <SkColor.h> +#include <SkImageInfo.h> +#include <SkRefCnt.h> + #include <gtest/gtest.h> #include <memory> #include <unordered_map> +class SkCanvas; +class SkMatrix; +class SkPath; +struct SkRect; + namespace android { namespace uirenderer { diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp index 03aeb55f129b..a07cdf720b50 100644 --- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp +++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp @@ -14,7 +14,17 @@ * limitations under the License. */ -#include <SkImagePriv.h> +#include <SkBitmap.h> +#include <SkBlendMode.h> +#include <SkCanvas.h> +#include <SkImage.h> +#include <SkImageInfo.h> +#include <SkPaint.h> +#include <SkRect.h> +#include <SkRefCnt.h> +#include <SkSamplingOptions.h> +#include <SkShader.h> +#include <SkTileMode.h> #include "hwui/Paint.h" #include "TestSceneBase.h" #include "tests/common/BitmapAllocationTestUtils.h" diff --git a/libs/hwui/tests/common/scenes/HwBitmap565.cpp b/libs/hwui/tests/common/scenes/HwBitmap565.cpp index cbdb756b8fa7..de0ef6d595f8 100644 --- a/libs/hwui/tests/common/scenes/HwBitmap565.cpp +++ b/libs/hwui/tests/common/scenes/HwBitmap565.cpp @@ -18,6 +18,12 @@ #include "tests/common/BitmapAllocationTestUtils.h" #include "utils/Color.h" +#include <SkBitmap.h> +#include <SkBlendMode.h> +#include <SkCanvas.h> +#include <SkPaint.h> +#include <SkRefCnt.h> + class HwBitmap565; static TestScene::Registrar _HwBitmap565(TestScene::Info{ diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp index 564354f04674..0d5ca6df9ff3 100644 --- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp +++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp @@ -17,6 +17,7 @@ #include "TestSceneBase.h" #include "utils/Color.h" +#include <SkColorSpace.h> #include <SkGradientShader.h> #include <SkImagePriv.h> #include <ui/PixelFormat.h> diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp index d031923a112b..4a5d9468cd88 100644 --- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp +++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp @@ -17,7 +17,16 @@ #include "TestSceneBase.h" #include "tests/common/TestListViewSceneBase.h" #include "hwui/Paint.h" +#include <SkBitmap.h> +#include <SkCanvas.h> +#include <SkColor.h> #include <SkFont.h> +#include <SkFontTypes.h> +#include <SkPaint.h> +#include <SkPoint.h> +#include <SkRect.h> +#include <SkRefCnt.h> +#include <SkScalar.h> #include <cstdio> class ListViewAnimation; @@ -48,7 +57,7 @@ class ListViewAnimation : public TestListViewSceneBase { 128 * 3; paint.setColor(bgDark ? Color::White : Color::Grey_700); - SkFont font; + SkFont font; font.setSize(size / 2); char charToShow = 'A' + (rand() % 26); const SkPoint pos = {SkIntToScalar(size / 2), diff --git a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp index edadf78db051..13a438199ae5 100644 --- a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp +++ b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp @@ -19,19 +19,57 @@ #include "utils/Color.h" #include "hwui/Paint.h" +#include <SkBitmap.h> +#include <SkBlendMode.h> +#include <SkFont.h> + class MagnifierAnimation; +using Rect = android::uirenderer::Rect; + static TestScene::Registrar _Magnifier(TestScene::Info{ "magnifier", "A sample magnifier using Readback", TestScene::simpleCreateScene<MagnifierAnimation>}); +class BlockingCopyRequest : public CopyRequest { + sk_sp<Bitmap> mDestination; + std::mutex mLock; + std::condition_variable mCondVar; + CopyResult mResult; + +public: + BlockingCopyRequest(::Rect rect, sk_sp<Bitmap> bitmap) + : CopyRequest(rect), mDestination(bitmap) {} + + virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) override { + SkBitmap bitmap; + mDestination->getSkBitmap(&bitmap); + return bitmap; + } + + virtual void onCopyFinished(CopyResult result) override { + std::unique_lock _lock{mLock}; + mResult = result; + mCondVar.notify_all(); + } + + CopyResult waitForResult() { + std::unique_lock _lock{mLock}; + mCondVar.wait(_lock); + return mResult; + } +}; + class MagnifierAnimation : public TestScene { public: sp<RenderNode> card; sp<RenderNode> zoomImageView; + sk_sp<Bitmap> magnifier; + std::shared_ptr<BlockingCopyRequest> copyRequest; void createContent(int width, int height, Canvas& canvas) override { magnifier = TestUtils::createBitmap(200, 100); + setupCopyRequest(); SkBitmap temp; magnifier->getSkBitmap(&temp); temp.eraseColor(Color::White); @@ -61,19 +99,20 @@ public: canvas.enableZ(false); } + void setupCopyRequest() { + constexpr int x = 90; + constexpr int y = 325; + copyRequest = std::make_shared<BlockingCopyRequest>( + ::Rect(x, y, x + magnifier->width(), y + magnifier->height()), magnifier); + } + void doFrame(int frameNr) override { int curFrame = frameNr % 150; card->mutateStagingProperties().setTranslationX(curFrame); card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); if (renderTarget) { - SkBitmap temp; - magnifier->getSkBitmap(&temp); - constexpr int x = 90; - constexpr int y = 325; - RenderProxy::copySurfaceInto(renderTarget.get(), x, y, x + magnifier->width(), - y + magnifier->height(), &temp); + RenderProxy::copySurfaceInto(renderTarget.get(), copyRequest); + copyRequest->waitForResult(); } } - - sk_sp<Bitmap> magnifier; }; diff --git a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp index 716d3979bdcb..3caaf8236d8a 100644 --- a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp +++ b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp @@ -16,6 +16,12 @@ #include "TestSceneBase.h" +#include <SkBitmap.h> +#include <SkCanvas.h> +#include <SkPaint.h> +#include <SkRect.h> +#include <SkRefCnt.h> + class ReadbackFromHardware; static TestScene::Registrar _SaveLayer(TestScene::Info{ diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp index 1c2507867f6e..27948f8b4b43 100644 --- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp +++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp @@ -17,6 +17,11 @@ #include "TestSceneBase.h" #include "utils/Color.h" +#include <SkBitmap.h> +#include <SkBlendMode.h> +#include <SkColor.h> +#include <SkRefCnt.h> + class RecentsAnimation; static TestScene::Registrar _Recents(TestScene::Info{ diff --git a/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp b/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp index a0bc5aa245d5..2aeb42cc0e20 100644 --- a/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp +++ b/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp @@ -16,7 +16,8 @@ #include "TestSceneBase.h" -#include <SkColorMatrixFilter.h> +#include <SkColorFilter.h> +#include <SkColorMatrix.h> #include <SkGradientShader.h> class SimpleColorMatrixAnimation; diff --git a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp index e677549b7894..7d3ca9642458 100644 --- a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp +++ b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp @@ -14,7 +14,15 @@ * limitations under the License. */ +#include <SkBitmap.h> +#include <SkCanvas.h> +#include <SkColor.h> #include <SkFont.h> +#include <SkFontTypes.h> +#include <SkPaint.h> +#include <SkPoint.h> +#include <SkRefCnt.h> +#include <SkRRect.h> #include <cstdio> #include "TestSceneBase.h" #include "hwui/Paint.h" @@ -130,7 +138,7 @@ private: roundRectPaint.setColor(Color::White); if (addHolePunch) { // Punch a hole but then cover it up, we don't want to actually see it - canvas.punchHole(SkRRect::MakeRect(SkRect::MakeWH(itemWidth, itemHeight))); + canvas.punchHole(SkRRect::MakeRect(SkRect::MakeWH(itemWidth, itemHeight)), 1.f); } canvas.drawRoundRect(0, 0, itemWidth, itemHeight, dp(6), dp(6), roundRectPaint); @@ -227,4 +235,4 @@ class StretchyUniformLayerListViewHolePunch : public StretchyListViewAnimation { StretchEffectBehavior stretchBehavior() override { return StretchEffectBehavior::UniformScale; } bool haveHolePunch() override { return true; } bool forceLayer() override { return true; } -};
\ No newline at end of file +}; diff --git a/libs/hwui/tests/common/scenes/TvApp.cpp b/libs/hwui/tests/common/scenes/TvApp.cpp index c6219c485b85..aff8ca1e26c7 100644 --- a/libs/hwui/tests/common/scenes/TvApp.cpp +++ b/libs/hwui/tests/common/scenes/TvApp.cpp @@ -14,7 +14,12 @@ * limitations under the License. */ +#include "SkBitmap.h" #include "SkBlendMode.h" +#include "SkColorFilter.h" +#include "SkFont.h" +#include "SkImageInfo.h" +#include "SkRefCnt.h" #include "TestSceneBase.h" #include "tests/common/BitmapAllocationTestUtils.h" #include "hwui/Paint.h" diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp index 2cf3456694b0..d2b1ef91a898 100644 --- a/libs/hwui/tests/unit/CanvasOpTests.cpp +++ b/libs/hwui/tests/unit/CanvasOpTests.cpp @@ -23,9 +23,17 @@ #include <tests/common/CallCountingCanvas.h> -#include "SkPictureRecorder.h" +#include "SkBitmap.h" +#include "SkCanvas.h" #include "SkColor.h" +#include "SkImageInfo.h" #include "SkLatticeIter.h" +#include "SkPaint.h" +#include "SkPath.h" +#include "SkPictureRecorder.h" +#include "SkRRect.h" +#include "SkRect.h" +#include "SkRegion.h" #include "pipeline/skia/AnimatedDrawables.h" #include <SkNoDrawCanvas.h> diff --git a/libs/hwui/tests/unit/EglManagerTests.cpp b/libs/hwui/tests/unit/EglManagerTests.cpp index 7f2e1589ae6c..ec9ab90fa46b 100644 --- a/libs/hwui/tests/unit/EglManagerTests.cpp +++ b/libs/hwui/tests/unit/EglManagerTests.cpp @@ -20,6 +20,8 @@ #include "renderthread/RenderEffectCapabilityQuery.h" #include "tests/common/TestContext.h" +#include <SkColorSpace.h> + using namespace android; using namespace android::uirenderer; using namespace android::uirenderer::renderthread; diff --git a/libs/hwui/tests/unit/FatalTestCanvas.h b/libs/hwui/tests/unit/FatalTestCanvas.h index 2a74afc5bb7a..96a0c6114682 100644 --- a/libs/hwui/tests/unit/FatalTestCanvas.h +++ b/libs/hwui/tests/unit/FatalTestCanvas.h @@ -19,6 +19,8 @@ #include <SkCanvas.h> #include <gtest/gtest.h> +class SkRRect; + namespace { class TestCanvasBase : public SkCanvas { diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp index 974d85a453db..576e9466d322 100644 --- a/libs/hwui/tests/unit/ShaderCacheTests.cpp +++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp @@ -25,6 +25,8 @@ #include <cstdint> #include "FileBlobCache.h" #include "pipeline/skia/ShaderCache.h" +#include <SkData.h> +#include <SkRefCnt.h> using namespace android::uirenderer::skiapipeline; diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp index dc1b2e668dd0..c1ddbd36bcfd 100644 --- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp +++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp @@ -16,9 +16,14 @@ #include "tests/common/TestUtils.h" +#include <SkBitmap.h> +#include <SkBlendMode.h> +#include <SkColor.h> #include <SkColorMatrixFilter.h> #include <SkColorSpace.h> -#include <SkImagePriv.h> +#include <SkImageInfo.h> +#include <SkPaint.h> +#include <SkPath.h> #include <SkPathOps.h> #include <SkShader.h> #include <gtest/gtest.h> diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp index dae3c9435712..50d9f5683a8b 100644 --- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp +++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp @@ -18,6 +18,7 @@ #include <hwui/Paint.h> #include <SkCanvasStateUtils.h> +#include <SkColorSpace.h> #include <SkPicture.h> #include <SkPictureRecorder.h> #include <gtest/gtest.h> diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp index 60ae6044cd5b..7419f8fd89f1 100644 --- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp +++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp @@ -404,7 +404,9 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) { EXPECT_TRUE(pipeline->isSurfaceReady()); renderThread.destroyRenderingContext(); EXPECT_FALSE(pipeline->isSurfaceReady()); - LOG_ALWAYS_FATAL_IF(pipeline->isSurfaceReady()); + + pipeline->makeCurrent(); + EXPECT_TRUE(pipeline->isSurfaceReady()); } RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, pictureCallback) { diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp index 15ecf5831f3a..ced667eb76e5 100644 --- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp +++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp @@ -17,6 +17,7 @@ #include <VectorDrawable.h> #include <gtest/gtest.h> +#include <SkCanvas.h> #include <SkClipStack.h> #include <SkSurface_Base.h> #include <string.h> diff --git a/libs/hwui/tests/unit/TypefaceTests.cpp b/libs/hwui/tests/unit/TypefaceTests.cpp index ab23448ab93f..499afa039d1f 100644 --- a/libs/hwui/tests/unit/TypefaceTests.cpp +++ b/libs/hwui/tests/unit/TypefaceTests.cpp @@ -21,8 +21,11 @@ #include <sys/stat.h> #include <utils/Log.h> +#include "SkData.h" #include "SkFontMgr.h" +#include "SkRefCnt.h" #include "SkStream.h" +#include "SkTypeface.h" #include "hwui/MinikinSkia.h" #include "hwui/Typeface.h" @@ -61,7 +64,7 @@ std::shared_ptr<minikin::FontFamily> buildFamily(const char* fileName) { std::vector<minikin::FontVariation>()); std::vector<std::shared_ptr<minikin::Font>> fonts; fonts.push_back(minikin::Font::Builder(font).build()); - return std::make_shared<minikin::FontFamily>(std::move(fonts)); + return minikin::FontFamily::create(std::move(fonts)); } std::vector<std::shared_ptr<minikin::FontFamily>> makeSingleFamlyVector(const char* fileName) { @@ -70,7 +73,8 @@ std::vector<std::shared_ptr<minikin::FontFamily>> makeSingleFamlyVector(const ch TEST(TypefaceTest, resolveDefault_and_setDefaultTest) { std::unique_ptr<Typeface> regular(Typeface::createFromFamilies( - makeSingleFamlyVector(kRobotoVariable), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + makeSingleFamlyVector(kRobotoVariable), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE, + nullptr /* fallback */)); EXPECT_EQ(regular.get(), Typeface::resolveDefault(regular.get())); // Keep the original to restore it later. @@ -348,24 +352,24 @@ TEST(TypefaceTest, createAbsolute) { TEST(TypefaceTest, createFromFamilies_Single) { // In Java, new // Typeface.Builder("Roboto-Regular.ttf").setWeight(400).setItalic(false).build(); - std::unique_ptr<Typeface> regular( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 400, false)); + std::unique_ptr<Typeface> regular(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 400, false, nullptr /* fallback */)); EXPECT_EQ(400, regular->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, regular->fStyle.slant()); EXPECT_EQ(Typeface::kNormal, regular->fAPIStyle); // In Java, new // Typeface.Builder("Roboto-Regular.ttf").setWeight(700).setItalic(false).build(); - std::unique_ptr<Typeface> bold( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 700, false)); + std::unique_ptr<Typeface> bold(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 700, false, nullptr /* fallback */)); EXPECT_EQ(700, bold->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, bold->fStyle.slant()); EXPECT_EQ(Typeface::kBold, bold->fAPIStyle); // In Java, new // Typeface.Builder("Roboto-Regular.ttf").setWeight(400).setItalic(true).build(); - std::unique_ptr<Typeface> italic( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 400, true)); + std::unique_ptr<Typeface> italic(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 400, true, nullptr /* fallback */)); EXPECT_EQ(400, italic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, italic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); @@ -373,8 +377,8 @@ TEST(TypefaceTest, createFromFamilies_Single) { // In Java, // new // Typeface.Builder("Roboto-Regular.ttf").setWeight(700).setItalic(true).build(); - std::unique_ptr<Typeface> boldItalic( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 700, true)); + std::unique_ptr<Typeface> boldItalic(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 700, true, nullptr /* fallback */)); EXPECT_EQ(700, boldItalic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, boldItalic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); @@ -382,8 +386,8 @@ TEST(TypefaceTest, createFromFamilies_Single) { // In Java, // new // Typeface.Builder("Roboto-Regular.ttf").setWeight(1100).setItalic(false).build(); - std::unique_ptr<Typeface> over1000( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 1100, false)); + std::unique_ptr<Typeface> over1000(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 1100, false, nullptr /* fallback */)); EXPECT_EQ(1000, over1000->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, over1000->fStyle.slant()); EXPECT_EQ(Typeface::kBold, over1000->fAPIStyle); @@ -391,30 +395,33 @@ TEST(TypefaceTest, createFromFamilies_Single) { TEST(TypefaceTest, createFromFamilies_Single_resolveByTable) { // In Java, new Typeface.Builder("Family-Regular.ttf").build(); - std::unique_ptr<Typeface> regular(Typeface::createFromFamilies( - makeSingleFamlyVector(kRegularFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr<Typeface> regular( + Typeface::createFromFamilies(makeSingleFamlyVector(kRegularFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(400, regular->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, regular->fStyle.slant()); EXPECT_EQ(Typeface::kNormal, regular->fAPIStyle); // In Java, new Typeface.Builder("Family-Bold.ttf").build(); - std::unique_ptr<Typeface> bold(Typeface::createFromFamilies( - makeSingleFamlyVector(kBoldFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr<Typeface> bold( + Typeface::createFromFamilies(makeSingleFamlyVector(kBoldFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(700, bold->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, bold->fStyle.slant()); EXPECT_EQ(Typeface::kBold, bold->fAPIStyle); // In Java, new Typeface.Builder("Family-Italic.ttf").build(); - std::unique_ptr<Typeface> italic(Typeface::createFromFamilies( - makeSingleFamlyVector(kItalicFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr<Typeface> italic( + Typeface::createFromFamilies(makeSingleFamlyVector(kItalicFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(400, italic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, italic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); // In Java, new Typeface.Builder("Family-BoldItalic.ttf").build(); - std::unique_ptr<Typeface> boldItalic( - Typeface::createFromFamilies(makeSingleFamlyVector(kBoldItalicFont), - RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr<Typeface> boldItalic(Typeface::createFromFamilies( + makeSingleFamlyVector(kBoldItalicFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE, + nullptr /* fallback */)); EXPECT_EQ(700, boldItalic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, boldItalic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); @@ -424,8 +431,9 @@ TEST(TypefaceTest, createFromFamilies_Family) { std::vector<std::shared_ptr<minikin::FontFamily>> families = { buildFamily(kRegularFont), buildFamily(kBoldFont), buildFamily(kItalicFont), buildFamily(kBoldItalicFont)}; - std::unique_ptr<Typeface> typeface(Typeface::createFromFamilies( - std::move(families), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr<Typeface> typeface( + Typeface::createFromFamilies(std::move(families), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(400, typeface->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, typeface->fStyle.slant()); } @@ -433,10 +441,24 @@ TEST(TypefaceTest, createFromFamilies_Family) { TEST(TypefaceTest, createFromFamilies_Family_withoutRegular) { std::vector<std::shared_ptr<minikin::FontFamily>> families = { buildFamily(kBoldFont), buildFamily(kItalicFont), buildFamily(kBoldItalicFont)}; - std::unique_ptr<Typeface> typeface(Typeface::createFromFamilies( - std::move(families), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr<Typeface> typeface( + Typeface::createFromFamilies(std::move(families), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(700, typeface->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, typeface->fStyle.slant()); } +TEST(TypefaceTest, createFromFamilies_Family_withFallback) { + std::vector<std::shared_ptr<minikin::FontFamily>> fallbackFamilies = { + buildFamily(kBoldFont), buildFamily(kItalicFont), buildFamily(kBoldItalicFont)}; + std::unique_ptr<Typeface> fallback( + Typeface::createFromFamilies(std::move(fallbackFamilies), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); + std::unique_ptr<Typeface> regular( + Typeface::createFromFamilies(makeSingleFamlyVector(kRegularFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, fallback.get())); + EXPECT_EQ(400, regular->fStyle.weight()); + EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, regular->fStyle.slant()); +} + } // namespace diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp index 6d4c57413f00..c1c21bd7dfbf 100644 --- a/libs/hwui/tests/unit/VectorDrawableTests.cpp +++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp @@ -21,6 +21,12 @@ #include "utils/MathUtils.h" #include "utils/VectorDrawableUtils.h" +#include <SkBitmap.h> +#include <SkCanvas.h> +#include <SkPath.h> +#include <SkRefCnt.h> +#include <SkShader.h> + #include <functional> namespace android { diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp index 45da008c3e8e..0e7b7ff4319d 100644 --- a/libs/input/MouseCursorController.cpp +++ b/libs/input/MouseCursorController.cpp @@ -22,14 +22,9 @@ #include "MouseCursorController.h" +#include <input/Input.h> #include <log/log.h> -#include <SkBitmap.h> -#include <SkBlendMode.h> -#include <SkCanvas.h> -#include <SkColor.h> -#include <SkPaint.h> - namespace { // Time to spend fading out the pointer completely. const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms @@ -292,7 +287,7 @@ void MouseCursorController::setDisplayViewport(const DisplayViewport& viewport, updatePointerLocked(); } -void MouseCursorController::updatePointerIcon(int32_t iconId) { +void MouseCursorController::updatePointerIcon(PointerIconStyle iconId) { std::scoped_lock lock(mLock); if (mLocked.requestedPointerType != iconId) { @@ -305,7 +300,7 @@ void MouseCursorController::updatePointerIcon(int32_t iconId) { void MouseCursorController::setCustomPointerIcon(const SpriteIcon& icon) { std::scoped_lock lock(mLock); - const int32_t iconId = mContext.getPolicy()->getCustomPointerIconId(); + const PointerIconStyle iconId = mContext.getPolicy()->getCustomPointerIconId(); mLocked.additionalMouseResources[iconId] = icon; mLocked.requestedPointerType = iconId; mLocked.updatePointerIcon = true; @@ -340,7 +335,7 @@ bool MouseCursorController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES( } bool MouseCursorController::doBitmapAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) { - std::map<int32_t, PointerAnimation>::const_iterator iter = + std::map<PointerIconStyle, PointerAnimation>::const_iterator iter = mLocked.animationResources.find(mLocked.requestedPointerType); if (iter == mLocked.animationResources.end()) { return false; @@ -386,10 +381,10 @@ void MouseCursorController::updatePointerLocked() REQUIRES(mLock) { if (mLocked.requestedPointerType == mContext.getPolicy()->getDefaultPointerIconId()) { mLocked.pointerSprite->setIcon(mLocked.pointerIcon); } else { - std::map<int32_t, SpriteIcon>::const_iterator iter = + std::map<PointerIconStyle, SpriteIcon>::const_iterator iter = mLocked.additionalMouseResources.find(mLocked.requestedPointerType); if (iter != mLocked.additionalMouseResources.end()) { - std::map<int32_t, PointerAnimation>::const_iterator anim_iter = + std::map<PointerIconStyle, PointerAnimation>::const_iterator anim_iter = mLocked.animationResources.find(mLocked.requestedPointerType); if (anim_iter != mLocked.animationResources.end()) { mLocked.animationFrameIndex = 0; diff --git a/libs/input/MouseCursorController.h b/libs/input/MouseCursorController.h index c0ab58bd2e7e..208d33d7c717 100644 --- a/libs/input/MouseCursorController.h +++ b/libs/input/MouseCursorController.h @@ -54,7 +54,7 @@ public: void unfade(PointerControllerInterface::Transition transition); void setDisplayViewport(const DisplayViewport& viewport, bool getAdditionalMouseResources); - void updatePointerIcon(int32_t iconId); + void updatePointerIcon(PointerIconStyle iconId); void setCustomPointerIcon(const SpriteIcon& icon); void reloadPointerResources(bool getAdditionalMouseResources); @@ -88,10 +88,10 @@ private: bool resourcesLoaded; - std::map<int32_t, SpriteIcon> additionalMouseResources; - std::map<int32_t, PointerAnimation> animationResources; + std::map<PointerIconStyle, SpriteIcon> additionalMouseResources; + std::map<PointerIconStyle, PointerAnimation> animationResources; - int32_t requestedPointerType; + PointerIconStyle requestedPointerType; int32_t buttonState; diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp index 10ea6512c724..54f893e165f7 100644 --- a/libs/input/PointerController.cpp +++ b/libs/input/PointerController.cpp @@ -264,7 +264,7 @@ void PointerController::setDisplayViewport(const DisplayViewport& viewport) { } } -void PointerController::updatePointerIcon(int32_t iconId) { +void PointerController::updatePointerIcon(PointerIconStyle iconId) { std::scoped_lock lock(getLock()); mCursorController.updatePointerIcon(iconId); } diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h index eab030f71e1a..33480e8fa194 100644 --- a/libs/input/PointerController.h +++ b/libs/input/PointerController.h @@ -65,7 +65,7 @@ public: BitSet32 spotIdBits, int32_t displayId); virtual void clearSpots(); - void updatePointerIcon(int32_t iconId); + void updatePointerIcon(PointerIconStyle iconId); void setCustomPointerIcon(const SpriteIcon& icon); void setInactivityTimeout(InactivityTimeout inactivityTimeout); void doInactivityTimeout(); diff --git a/libs/input/PointerControllerContext.h b/libs/input/PointerControllerContext.h index c2bc1e020279..1797428b343f 100644 --- a/libs/input/PointerControllerContext.h +++ b/libs/input/PointerControllerContext.h @@ -75,10 +75,11 @@ public: virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId) = 0; virtual void loadPointerResources(PointerResources* outResources, int32_t displayId) = 0; virtual void loadAdditionalMouseResources( - std::map<int32_t, SpriteIcon>* outResources, - std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0; - virtual int32_t getDefaultPointerIconId() = 0; - virtual int32_t getCustomPointerIconId() = 0; + std::map<PointerIconStyle, SpriteIcon>* outResources, + std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, + int32_t displayId) = 0; + virtual PointerIconStyle getDefaultPointerIconId() = 0; + virtual PointerIconStyle getCustomPointerIconId() = 0; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) = 0; }; diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp index 2b809eab4ae4..130b204954b4 100644 --- a/libs/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp @@ -131,8 +131,9 @@ void SpriteController::doUpdateSprites() { update.state.surfaceHeight = update.state.icon.height(); update.state.surfaceDrawn = false; update.state.surfaceVisible = false; - update.state.surfaceControl = obtainSurface( - update.state.surfaceWidth, update.state.surfaceHeight); + update.state.surfaceControl = + obtainSurface(update.state.surfaceWidth, update.state.surfaceHeight, + update.state.displayId); if (update.state.surfaceControl != NULL) { update.surfaceChanged = surfaceChanged = true; } @@ -168,8 +169,8 @@ void SpriteController::doUpdateSprites() { } } - // If surface is a new one, we have to set right layer stack. - if (update.surfaceChanged || update.state.dirty & DIRTY_DISPLAY_ID) { + // If surface has changed to a new display, we have to reparent it. + if (update.state.dirty & DIRTY_DISPLAY_ID) { t.reparent(update.state.surfaceControl, mParentSurfaceProvider(update.state.displayId)); needApplyTransaction = true; } @@ -242,15 +243,14 @@ void SpriteController::doUpdateSprites() { && (becomingVisible || (update.state.dirty & (DIRTY_HOTSPOT | DIRTY_ICON_STYLE)))) { Parcel p; - p.writeInt32(update.state.icon.style); + p.writeInt32(static_cast<int32_t>(update.state.icon.style)); p.writeFloat(update.state.icon.hotSpotX); p.writeFloat(update.state.icon.hotSpotY); // Pass cursor metadata in the sprite surface so that when Android is running as a // client OS (e.g. ARC++) the host OS can get the requested cursor metadata and // update mouse cursor in the host OS. - t.setMetadata( - update.state.surfaceControl, METADATA_MOUSE_CURSOR, p); + t.setMetadata(update.state.surfaceControl, gui::METADATA_MOUSE_CURSOR, p); } int32_t surfaceLayer = mOverlayLayer + update.state.layer; @@ -331,21 +331,28 @@ void SpriteController::ensureSurfaceComposerClient() { } } -sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) { +sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height, + int32_t displayId) { ensureSurfaceComposerClient(); - sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface( - String8("Sprite"), width, height, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eHidden | - ISurfaceComposerClient::eCursorWindow); - if (surfaceControl == NULL || !surfaceControl->isValid()) { + const sp<SurfaceControl> parent = mParentSurfaceProvider(displayId); + if (parent == nullptr) { + ALOGE("Failed to get the parent surface for pointers on display %d", displayId); + } + + const sp<SurfaceControl> surfaceControl = + mSurfaceComposerClient->createSurface(String8("Sprite"), width, height, + PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eHidden | + ISurfaceComposerClient::eCursorWindow, + parent ? parent->getHandle() : nullptr); + if (surfaceControl == nullptr || !surfaceControl->isValid()) { ALOGE("Error creating sprite surface."); - return NULL; + return nullptr; } return surfaceControl; } - // --- SpriteController::SpriteImpl --- SpriteController::SpriteImpl::SpriteImpl(const sp<SpriteController> controller) : diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h index 2e9cb9685c46..1f113c045360 100644 --- a/libs/input/SpriteController.h +++ b/libs/input/SpriteController.h @@ -265,7 +265,7 @@ private: void doDisposeSurfaces(); void ensureSurfaceComposerClient(); - sp<SurfaceControl> obtainSurface(int32_t width, int32_t height); + sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, int32_t displayId); }; } // namespace android diff --git a/libs/input/SpriteIcon.h b/libs/input/SpriteIcon.h index a257d7e89ebc..5f085bbd2374 100644 --- a/libs/input/SpriteIcon.h +++ b/libs/input/SpriteIcon.h @@ -19,6 +19,7 @@ #include <android/graphics/bitmap.h> #include <gui/Surface.h> +#include <input/Input.h> namespace android { @@ -26,12 +27,13 @@ namespace android { * Icon that a sprite displays, including its hotspot. */ struct SpriteIcon { - inline SpriteIcon() : style(0), hotSpotX(0), hotSpotY(0) {} - inline SpriteIcon(const graphics::Bitmap& bitmap, int32_t style, float hotSpotX, float hotSpotY) + inline SpriteIcon() : style(PointerIconStyle::TYPE_NULL), hotSpotX(0), hotSpotY(0) {} + inline SpriteIcon(const graphics::Bitmap& bitmap, PointerIconStyle style, float hotSpotX, + float hotSpotY) : bitmap(bitmap), style(style), hotSpotX(hotSpotX), hotSpotY(hotSpotY) {} graphics::Bitmap bitmap; - int32_t style; + PointerIconStyle style; float hotSpotX; float hotSpotY; @@ -41,7 +43,7 @@ struct SpriteIcon { inline void reset() { bitmap.reset(); - style = 0; + style = PointerIconStyle::TYPE_NULL; hotSpotX = 0; hotSpotY = 0; } diff --git a/libs/input/TouchSpotController.cpp b/libs/input/TouchSpotController.cpp index f7c685ff8ba6..4ac66c4ffb6a 100644 --- a/libs/input/TouchSpotController.cpp +++ b/libs/input/TouchSpotController.cpp @@ -23,12 +23,6 @@ #include <log/log.h> -#include <SkBitmap.h> -#include <SkBlendMode.h> -#include <SkCanvas.h> -#include <SkColor.h> -#include <SkPaint.h> - namespace { // Time to spend fading out the spot completely. const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp index f9752ed155df..a6a4115476df 100644 --- a/libs/input/tests/PointerController_test.cpp +++ b/libs/input/tests/PointerController_test.cpp @@ -14,17 +14,18 @@ * limitations under the License. */ -#include "mocks/MockSprite.h" -#include "mocks/MockSpriteController.h" - +#include <gmock/gmock.h> +#include <gtest/gtest.h> #include <input/PointerController.h> #include <input/SpriteController.h> #include <atomic> -#include <gmock/gmock.h> -#include <gtest/gtest.h> #include <thread> +#include "input/Input.h" +#include "mocks/MockSprite.h" +#include "mocks/MockSpriteController.h" + namespace android { enum TestCursorType { @@ -39,7 +40,6 @@ enum TestCursorType { using ::testing::AllOf; using ::testing::Field; -using ::testing::Mock; using ::testing::NiceMock; using ::testing::Return; using ::testing::Test; @@ -52,10 +52,12 @@ class MockPointerControllerPolicyInterface : public PointerControllerPolicyInter public: virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId) override; virtual void loadPointerResources(PointerResources* outResources, int32_t displayId) override; - virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources, - std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) override; - virtual int32_t getDefaultPointerIconId() override; - virtual int32_t getCustomPointerIconId() override; + virtual void loadAdditionalMouseResources( + std::map<PointerIconStyle, SpriteIcon>* outResources, + std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, + int32_t displayId) override; + virtual PointerIconStyle getDefaultPointerIconId() override; + virtual PointerIconStyle getCustomPointerIconId() override; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) override; bool allResourcesAreLoaded(); @@ -85,34 +87,33 @@ void MockPointerControllerPolicyInterface::loadPointerResources(PointerResources } void MockPointerControllerPolicyInterface::loadAdditionalMouseResources( - std::map<int32_t, SpriteIcon>* outResources, - std::map<int32_t, PointerAnimation>* outAnimationResources, - int32_t) { + std::map<PointerIconStyle, SpriteIcon>* outResources, + std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, int32_t) { SpriteIcon icon; PointerAnimation anim; // CURSOR_TYPE_ADDITIONAL doesn't have animation resource. int32_t cursorType = CURSOR_TYPE_ADDITIONAL; loadPointerIconForType(&icon, cursorType); - (*outResources)[cursorType] = icon; + (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon; // CURSOR_TYPE_ADDITIONAL_ANIM has animation resource. cursorType = CURSOR_TYPE_ADDITIONAL_ANIM; loadPointerIconForType(&icon, cursorType); anim.animationFrames.push_back(icon); anim.durationPerFrame = 10; - (*outResources)[cursorType] = icon; - (*outAnimationResources)[cursorType] = anim; + (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon; + (*outAnimationResources)[static_cast<PointerIconStyle>(cursorType)] = anim; additionalMouseResourcesLoaded = true; } -int32_t MockPointerControllerPolicyInterface::getDefaultPointerIconId() { - return CURSOR_TYPE_DEFAULT; +PointerIconStyle MockPointerControllerPolicyInterface::getDefaultPointerIconId() { + return static_cast<PointerIconStyle>(CURSOR_TYPE_DEFAULT); } -int32_t MockPointerControllerPolicyInterface::getCustomPointerIconId() { - return CURSOR_TYPE_CUSTOM; +PointerIconStyle MockPointerControllerPolicyInterface::getCustomPointerIconId() { + return static_cast<PointerIconStyle>(CURSOR_TYPE_CUSTOM); } bool MockPointerControllerPolicyInterface::allResourcesAreLoaded() { @@ -124,7 +125,7 @@ bool MockPointerControllerPolicyInterface::noResourcesAreLoaded() { } void MockPointerControllerPolicyInterface::loadPointerIconForType(SpriteIcon* icon, int32_t type) { - icon->style = type; + icon->style = static_cast<PointerIconStyle>(type); std::pair<float, float> hotSpot = getHotSpotCoordinatesForType(type); icon->hotSpotX = hotSpot.first; icon->hotSpotY = hotSpot.second; @@ -205,11 +206,11 @@ TEST_F(PointerControllerTest, useDefaultCursorTypeByDefault) { std::pair<float, float> hotspot = getHotSpotCoordinatesForType(CURSOR_TYPE_DEFAULT); EXPECT_CALL(*mPointerSprite, setVisible(true)); EXPECT_CALL(*mPointerSprite, setAlpha(1.0f)); - EXPECT_CALL(*mPointerSprite, setIcon( - AllOf( - Field(&SpriteIcon::style, CURSOR_TYPE_DEFAULT), - Field(&SpriteIcon::hotSpotX, hotspot.first), - Field(&SpriteIcon::hotSpotY, hotspot.second)))); + EXPECT_CALL(*mPointerSprite, + setIcon(AllOf(Field(&SpriteIcon::style, + static_cast<PointerIconStyle>(CURSOR_TYPE_DEFAULT)), + Field(&SpriteIcon::hotSpotX, hotspot.first), + Field(&SpriteIcon::hotSpotY, hotspot.second)))); mPointerController->reloadPointerResources(); } @@ -222,12 +223,11 @@ TEST_F(PointerControllerTest, updatePointerIcon) { std::pair<float, float> hotspot = getHotSpotCoordinatesForType(type); EXPECT_CALL(*mPointerSprite, setVisible(true)); EXPECT_CALL(*mPointerSprite, setAlpha(1.0f)); - EXPECT_CALL(*mPointerSprite, setIcon( - AllOf( - Field(&SpriteIcon::style, type), - Field(&SpriteIcon::hotSpotX, hotspot.first), - Field(&SpriteIcon::hotSpotY, hotspot.second)))); - mPointerController->updatePointerIcon(type); + EXPECT_CALL(*mPointerSprite, + setIcon(AllOf(Field(&SpriteIcon::style, static_cast<PointerIconStyle>(type)), + Field(&SpriteIcon::hotSpotX, hotspot.first), + Field(&SpriteIcon::hotSpotY, hotspot.second)))); + mPointerController->updatePointerIcon(static_cast<PointerIconStyle>(type)); } TEST_F(PointerControllerTest, setCustomPointerIcon) { @@ -239,17 +239,16 @@ TEST_F(PointerControllerTest, setCustomPointerIcon) { float hotSpotY = 20; SpriteIcon icon; - icon.style = style; + icon.style = static_cast<PointerIconStyle>(style); icon.hotSpotX = hotSpotX; icon.hotSpotY = hotSpotY; EXPECT_CALL(*mPointerSprite, setVisible(true)); EXPECT_CALL(*mPointerSprite, setAlpha(1.0f)); - EXPECT_CALL(*mPointerSprite, setIcon( - AllOf( - Field(&SpriteIcon::style, style), - Field(&SpriteIcon::hotSpotX, hotSpotX), - Field(&SpriteIcon::hotSpotY, hotSpotY)))); + EXPECT_CALL(*mPointerSprite, + setIcon(AllOf(Field(&SpriteIcon::style, static_cast<PointerIconStyle>(style)), + Field(&SpriteIcon::hotSpotX, hotSpotX), + Field(&SpriteIcon::hotSpotY, hotSpotY)))); mPointerController->setCustomPointerIcon(icon); } |