diff --git a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java index 4f9c32ade5..3fddd9d693 100644 --- a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java +++ b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java @@ -218,29 +218,6 @@ public class DebugTestInformationHandler extends TestInformationHandler { } } - case TestProtocol.REQUEST_USE_TEST_WORKSPACE_LAYOUT: { - useTestWorkspaceLayout( - LauncherSettings.Settings.ARG_DEFAULT_WORKSPACE_LAYOUT_TEST); - return response; - } - - case TestProtocol.REQUEST_USE_TEST2_WORKSPACE_LAYOUT: { - useTestWorkspaceLayout( - LauncherSettings.Settings.ARG_DEFAULT_WORKSPACE_LAYOUT_TEST2); - return response; - } - - case TestProtocol.REQUEST_USE_TAPL_WORKSPACE_LAYOUT: { - useTestWorkspaceLayout( - LauncherSettings.Settings.ARG_DEFAULT_WORKSPACE_LAYOUT_TAPL); - return response; - } - - case TestProtocol.REQUEST_USE_DEFAULT_WORKSPACE_LAYOUT: { - useTestWorkspaceLayout(null); - return response; - } - case TestProtocol.REQUEST_HOTSEAT_ICON_NAMES: { return getLauncherUIProperty(Bundle::putStringArrayList, l -> { ShortcutAndWidgetContainer hotseatIconsContainer = @@ -278,20 +255,4 @@ public class DebugTestInformationHandler extends TestInformationHandler { return super.call(method, arg, extras); } } - - private void useTestWorkspaceLayout(String layout) { - final long identity = Binder.clearCallingIdentity(); - try { - if (layout != null) { - LauncherSettings.Settings.call(mContext.getContentResolver(), - LauncherSettings.Settings.METHOD_SET_USE_TEST_WORKSPACE_LAYOUT_FLAG, - layout); - } else { - LauncherSettings.Settings.call(mContext.getContentResolver(), - LauncherSettings.Settings.METHOD_CLEAR_USE_TEST_WORKSPACE_LAYOUT_FLAG); - } - } finally { - Binder.restoreCallingIdentity(identity); - } - } } diff --git a/go/quickstep/res/values-am/strings.xml b/go/quickstep/res/values-am/strings.xml index ed3479783a..ffc59d931d 100644 --- a/go/quickstep/res/values-am/strings.xml +++ b/go/quickstep/res/values-am/strings.xml @@ -9,12 +9,12 @@ "ይቅር" "ቅንብሮች" "በማያ ገጹ ላይ ጽሑፍን ይተረጉሙ ወይም ያዳምጡ" - "እንደ በማያ ገጽዎ ላይ ያለ ጽሁፍ፣ የድር አድራሻዎች እና ቅጽበታዊ ገጽ እይታዎች ያሉ መረጃዎች ለGoogle ሊጋሩ ይችላሉ።\n\nምን መረጃ እንደሚያጋሩ ለመቀየር ወደ ""ቅንብሮች > መተግበሪያዎች > ነባሪ መተግበሪያዎች > ዲጂታል ረዳት መተግበሪያ"" ይሂዱ።" + "እንደ በማያ ገፅዎ ላይ ያለ ጽሁፍ፣ የድር አድራሻዎች እና ቅጽበታዊ ገፅ እይታዎች ያሉ መረጃዎች ለGoogle ሊጋሩ ይችላሉ።\n\nምን መረጃ እንደሚያጋሩ ለመቀየር ወደ ""ቅንብሮች > መተግበሪያዎች > ነባሪ መተግበሪያዎች > ዲጂታል ረዳት መተግበሪያ"" ይሂዱ።" "ይህንን ባህሪ ለመጠቀም ረዳት ይምረጡ" "በማያ ገጽዎ ላይ ጽሑፍን ለማዳመጥ ወይም ለመተርጎም በቅንብሮች ውስጥ የዲጂታል ረዳት መተግበሪያን ይምረጡ" "ይህንን ባህሪ ለመጠቀም ረዳትዎን ይቀይሩ" "በማያ ገጽዎ ላይ ጽሑፍን ለማዳመጥ ወይም ለመተርጎም በቅንብሮች ውስጥ የዲጂታል ረዳት መተግበሪያዎን ይቀይሩ" - "በዚህ ማያ ገጽ ላይ ጽሁፍ ለማዳመጥ እዚህ መታ ያድርጉ" - "በዚህ ማያ ገጽ ላይ ጽሁፍ ለመተርጎም እዚህ መታ ያድርጉ" + "በዚህ ማያ ገፅ ላይ ጽሁፍ ለማዳመጥ እዚህ መታ ያድርጉ" + "በዚህ ማያ ገፅ ላይ ጽሁፍ ለመተርጎም እዚህ መታ ያድርጉ" "ይህ መተግበሪያ ሊጋራ አይችልም" diff --git a/res/color/app_subtitle_text_light.xml b/quickstep/res/color-night/quick_switch_view_background.xml similarity index 88% rename from res/color/app_subtitle_text_light.xml rename to quickstep/res/color-night/quick_switch_view_background.xml index fb00baac6c..7280918645 100644 --- a/res/color/app_subtitle_text_light.xml +++ b/quickstep/res/color-night/quick_switch_view_background.xml @@ -1,12 +1,9 @@ - + diff --git a/quickstep/res/color/all_set_bg_primary.xml b/quickstep/res/color/all_set_bg_primary.xml new file mode 100644 index 0000000000..4cf857d0e6 --- /dev/null +++ b/quickstep/res/color/all_set_bg_primary.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/res/color/app_subtitle_text_dark.xml b/quickstep/res/color/all_set_bg_tertiary.xml similarity index 84% rename from res/color/app_subtitle_text_dark.xml rename to quickstep/res/color/all_set_bg_tertiary.xml index 220d10fc8f..e62b094971 100644 --- a/res/color/app_subtitle_text_dark.xml +++ b/quickstep/res/color/all_set_bg_tertiary.xml @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - + + diff --git a/res/color/app_title_text_light.xml b/quickstep/res/color/quick_switch_view_background.xml similarity index 88% rename from res/color/app_title_text_light.xml rename to quickstep/res/color/quick_switch_view_background.xml index bb5297319d..0eb2a6b915 100644 --- a/res/color/app_title_text_light.xml +++ b/quickstep/res/color/quick_switch_view_background.xml @@ -1,12 +1,9 @@ - + diff --git a/quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml b/quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml index 15843af154..2a4f0872e3 100644 --- a/quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml +++ b/quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml @@ -17,6 +17,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:shape="rectangle"> - + diff --git a/quickstep/res/drawable/keyboard_quick_switch_view_background.xml b/quickstep/res/drawable/keyboard_quick_switch_view_background.xml index 19aaed46b0..573c93ac1d 100644 --- a/quickstep/res/drawable/keyboard_quick_switch_view_background.xml +++ b/quickstep/res/drawable/keyboard_quick_switch_view_background.xml @@ -16,6 +16,6 @@ - + diff --git a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml index 174a70459b..04e87be412 100644 --- a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml +++ b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml @@ -23,30 +23,42 @@ android:importantForAccessibility="yes" android:background="@drawable/keyboard_quick_switch_task_view_background" android:clipToOutline="true" - launcher:borderColor="?androidprv:attr/materialColorSecondaryContainer"> + launcher:borderColor="?androidprv:attr/materialColorOutline"> - + app:layout_constraintEnd_toEndOf="parent"> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/thumbnail2"/> + + + + diff --git a/quickstep/res/layout-land/redesigned_gesture_tutorial_mock_hotseat.xml b/quickstep/res/layout-land/redesigned_gesture_tutorial_mock_hotseat.xml index 6c08d14b6b..af86ae735d 100644 --- a/quickstep/res/layout-land/redesigned_gesture_tutorial_mock_hotseat.xml +++ b/quickstep/res/layout-land/redesigned_gesture_tutorial_mock_hotseat.xml @@ -22,49 +22,46 @@ android:paddingVertical="26dp" android:paddingHorizontal="56dp"> + + + android:clipToOutline="true" /> + android:clipToOutline="true" /> + android:clipToOutline="true" /> + android:clipToOutline="true" /> \ No newline at end of file diff --git a/quickstep/res/layout-land/redesigned_gesture_tutorial_tablet_mock_hotseat.xml b/quickstep/res/layout-land/redesigned_gesture_tutorial_tablet_mock_hotseat.xml new file mode 100644 index 0000000000..983c15b23b --- /dev/null +++ b/quickstep/res/layout-land/redesigned_gesture_tutorial_tablet_mock_hotseat.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/layout/bubble_view.xml b/quickstep/res/layout/bubble_view.xml new file mode 100644 index 0000000000..0b1ed9f343 --- /dev/null +++ b/quickstep/res/layout/bubble_view.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/layout/bubblebar_item_view.xml b/quickstep/res/layout/bubblebar_item_view.xml new file mode 100644 index 0000000000..64fc4dfa3d --- /dev/null +++ b/quickstep/res/layout/bubblebar_item_view.xml @@ -0,0 +1,21 @@ + + + diff --git a/quickstep/res/layout/keyboard_quick_switch_overview.xml b/quickstep/res/layout/keyboard_quick_switch_overview.xml index 7b34710dd3..062a9c9fa1 100644 --- a/quickstep/res/layout/keyboard_quick_switch_overview.xml +++ b/quickstep/res/layout/keyboard_quick_switch_overview.xml @@ -20,35 +20,47 @@ xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/keyboard_quick_switch_taskview_width" android:layout_height="@dimen/keyboard_quick_switch_taskview_height" - android:background="@drawable/keyboard_quick_switch_overview_button_background" android:clipToOutline="true" android:importantForAccessibility="yes" - launcher:borderColor="?androidprv:attr/materialColorSecondaryContainer"> + launcher:borderColor="?androidprv:attr/materialColorOutline"> - - - + app:layout_constraintEnd_toEndOf="parent"> + + + + + + diff --git a/quickstep/res/layout/keyboard_quick_switch_taskview.xml b/quickstep/res/layout/keyboard_quick_switch_taskview.xml index 15b12dc9ef..691df6e8f6 100644 --- a/quickstep/res/layout/keyboard_quick_switch_taskview.xml +++ b/quickstep/res/layout/keyboard_quick_switch_taskview.xml @@ -23,7 +23,17 @@ android:importantForAccessibility="yes" android:background="@drawable/keyboard_quick_switch_task_view_background" android:clipToOutline="true" - launcher:borderColor="?androidprv:attr/materialColorSecondaryContainer"> + launcher:borderColor="?androidprv:attr/materialColorOutline"> + + + + diff --git a/quickstep/res/layout/keyboard_quick_switch_view.xml b/quickstep/res/layout/keyboard_quick_switch_view.xml index 64d3f67eda..58c0c40980 100644 --- a/quickstep/res/layout/keyboard_quick_switch_view.xml +++ b/quickstep/res/layout/keyboard_quick_switch_view.xml @@ -18,7 +18,6 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingVertical="@dimen/keyboard_quick_switch_view_spacing" android:layout_marginTop="@dimen/keyboard_quick_switch_margin_top" android:layout_marginHorizontal="@dimen/keyboard_quick_switch_margin_ends" android:background="@drawable/keyboard_quick_switch_view_background" @@ -44,7 +43,9 @@ + android:layout_height="wrap_content" + android:paddingVertical="@dimen/keyboard_quick_switch_view_spacing" + android:clipToPadding="false"/> diff --git a/quickstep/res/layout/redesigned_gesture_tutorial_foldable_mock_hotseat.xml b/quickstep/res/layout/redesigned_gesture_tutorial_foldable_mock_hotseat.xml new file mode 100644 index 0000000000..b41eb8d570 --- /dev/null +++ b/quickstep/res/layout/redesigned_gesture_tutorial_foldable_mock_hotseat.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/layout/redesigned_gesture_tutorial_mock_hotseat.xml b/quickstep/res/layout/redesigned_gesture_tutorial_mock_hotseat.xml index b1c8b31621..e93a0fca74 100644 --- a/quickstep/res/layout/redesigned_gesture_tutorial_mock_hotseat.xml +++ b/quickstep/res/layout/redesigned_gesture_tutorial_mock_hotseat.xml @@ -23,54 +23,45 @@ android:paddingStart="26dp" android:paddingEnd="26dp"> + + + android:clipToOutline="true" /> + android:clipToOutline="true" /> + android:clipToOutline="true" /> + android:clipToOutline="true" /> + app:layout_constraintTop_toBottomOf="@id/hotseat_flow" /> \ No newline at end of file diff --git a/quickstep/res/layout/redesigned_gesture_tutorial_tablet_mock_hotseat.xml b/quickstep/res/layout/redesigned_gesture_tutorial_tablet_mock_hotseat.xml new file mode 100644 index 0000000000..b41eb8d570 --- /dev/null +++ b/quickstep/res/layout/redesigned_gesture_tutorial_tablet_mock_hotseat.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml index faafec718a..e981730710 100644 --- a/quickstep/res/layout/task.xml +++ b/quickstep/res/layout/task.xml @@ -24,7 +24,7 @@ android:clipChildren="false" android:defaultFocusHighlightEnabled="false" android:focusable="true" - launcher:borderColor="?androidprv:attr/materialColorSecondaryContainer"> + launcher:borderColor="?androidprv:attr/materialColorOutline"> + launcher:borderColor="?androidprv:attr/materialColorOutline"> + launcher:borderColor="?androidprv:attr/materialColorOutline"> - + - - + android:background="@drawable/taskbar_divider_bg" /> + \ No newline at end of file diff --git a/quickstep/res/layout/taskbar_divider_popup_menu.xml b/quickstep/res/layout/taskbar_divider_popup_menu.xml new file mode 100644 index 0000000000..195443ead9 --- /dev/null +++ b/quickstep/res/layout/taskbar_divider_popup_menu.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/raw-land/all_set_page_bg.json b/quickstep/res/raw-land/all_set_page_bg.json new file mode 100644 index 0000000000..9e94c47a63 --- /dev/null +++ b/quickstep/res/raw-land/all_set_page_bg.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":181,"w":796,"h":412,"nm":"SUW_Welcome_Handheld_Landscape_Dynamic","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".primary","cl":"primary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-55]},{"t":180,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.942},"o":{"x":0.167,"y":0.167},"t":0,"s":[700.266,85.857,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.043},"t":95,"s":[700.266,-103.727,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[700.266,85.857,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[-18.2,18.2,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[100.594,-128.921],[118.85,-93.491],[148.984,-67.406],[148.684,-27.55],[163.244,9.552],[144.457,44.702],[140.106,84.321],[107.136,106.715],[84.872,139.773],[45.271,144.279],[10.194,163.205],[-26.964,148.792],[-66.818,149.249],[-93.023,119.218],[-128.524,101.101],[-137.771,62.332],[-160.786,29.793],[-150.957,-8.833],[-156.215,-48.341],[-129.561,-77.974],[-115.856,-115.401],[-78.484,-129.253],[-48.956,-156.023],[-9.427,-150.921],[29.159,-160.903],[61.789,-138.015]],"o":[[-100.594,128.921],[-118.85,93.491],[-148.984,67.406],[-148.684,27.55],[-163.244,-9.552],[-144.456,-44.702],[-140.106,-84.321],[-107.136,-106.715],[-84.872,-139.773],[-45.271,-144.279],[-10.194,-163.205],[26.964,-148.792],[66.818,-149.249],[93.023,-119.218],[128.524,-101.101],[137.771,-62.332],[160.786,-29.793],[150.957,8.833],[156.215,48.341],[129.561,77.974],[115.856,115.4],[78.484,129.253],[48.956,156.023],[9.427,150.921],[-29.159,160.903],[-61.789,138.015]],"v":[[975.226,761.299],[707.165,899.424],[509.8,1127.42],[208.253,1125.148],[-72.46,1235.308],[-338.41,1093.162],[-638.164,1060.25],[-807.592,810.792],[-1057.715,642.348],[-1091.808,342.727],[-1235.002,77.338],[-1125.948,-203.807],[-1129.407,-505.342],[-902.191,-703.604],[-765.123,-972.207],[-471.796,-1042.166],[-225.603,-1216.305],[66.637,-1141.935],[365.557,-1181.715],[589.761,-980.053],[872.928,-876.361],[977.734,-593.606],[1180.277,-370.197],[1141.675,-71.124],[1217.196,220.821],[1044.029,467.699]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.713725490196,0.556862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"k":[{"s":[10.989],"t":0,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[10.989],"t":180,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":181,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".tertiary","cl":"tertiary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.047]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.773],"y":[-0.035]},"t":95,"s":[-67]},{"t":180,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.073]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[319.023]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.773],"y":[-0.054]},"t":95,"s":[388.573]},{"t":180,"s":[319.023]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[0.927]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[565.531]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.773],"y":[0.054]},"t":95,"s":[482.331]},{"t":180,"s":[565.531]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[65,65,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[1193.125,1815.766],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.901960784314,0.764705882353,0.423529411765,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[398,206,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[2472,5352],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.125489994124,0.1294119891,0.141176006841,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/raw-sw600dp-land/all_set_page_bg.json b/quickstep/res/raw-sw600dp-land/all_set_page_bg.json index f53128cbdf..63b64da7fa 100644 --- a/quickstep/res/raw-sw600dp-land/all_set_page_bg.json +++ b/quickstep/res/raw-sw600dp-land/all_set_page_bg.json @@ -1 +1 @@ -{"v":"5.8.1","fr":60,"ip":0,"op":180,"w":1280,"h":800,"nm":"3Second_MainWelcomeScreen_Tablet_Landscape_V02","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[288,540,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[25,25,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"F4BA9E","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[375.832,-1006.545,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":95,"s":[375.832,-1811,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[375.832,-1006.545,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[110,110,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.956862745098,0.729411764706,0.619607843137,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"C0C9C0","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[57]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":95,"s":[75]},{"t":180,"s":[57]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[2618]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":95,"s":[2442]},{"t":180,"s":[2618]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[891]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":95,"s":[694]},{"t":180,"s":[891]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[120,120,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.752941176471,0.788235294118,0.752941176471,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.8.1","fr":60,"ip":0,"op":181,"w":841,"h":701,"nm":"SUW_WelcomeScreen_FoldableOpen_Dynamic","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".primary","cl":"primary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[55]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.939},"o":{"x":0.167,"y":0.167},"t":0,"s":[140.975,228.318,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.045},"t":95,"s":[140.975,47.65,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[140.975,228.318,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[18,18,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[100.594,-128.921],[118.85,-93.491],[148.984,-67.406],[148.684,-27.55],[163.244,9.552],[144.457,44.702],[140.106,84.321],[107.136,106.715],[84.872,139.773],[45.271,144.279],[10.194,163.205],[-26.964,148.792],[-66.818,149.249],[-93.023,119.218],[-128.524,101.101],[-137.771,62.332],[-160.786,29.793],[-150.957,-8.833],[-156.215,-48.341],[-129.561,-77.974],[-115.856,-115.401],[-78.484,-129.253],[-48.956,-156.023],[-9.427,-150.921],[29.159,-160.903],[61.789,-138.015]],"o":[[-100.594,128.921],[-118.85,93.491],[-148.984,67.406],[-148.684,27.55],[-163.244,-9.552],[-144.456,-44.702],[-140.106,-84.321],[-107.136,-106.715],[-84.872,-139.773],[-45.271,-144.279],[-10.194,-163.205],[26.964,-148.792],[66.818,-149.249],[93.023,-119.218],[128.524,-101.101],[137.771,-62.332],[160.786,-29.793],[150.957,8.833],[156.215,48.341],[129.561,77.974],[115.856,115.4],[78.484,129.253],[48.956,156.023],[9.427,150.921],[-29.159,160.903],[-61.789,138.015]],"v":[[975.226,761.299],[707.165,899.424],[509.8,1127.42],[208.253,1125.148],[-72.46,1235.308],[-338.41,1093.162],[-638.164,1060.25],[-807.592,810.792],[-1057.715,642.348],[-1091.808,342.727],[-1235.002,77.338],[-1125.948,-203.807],[-1129.407,-505.342],[-902.191,-703.604],[-765.123,-972.207],[-471.796,-1042.166],[-225.603,-1216.305],[66.637,-1141.935],[365.557,-1181.715],[589.761,-980.053],[872.928,-876.361],[977.734,-593.606],[1180.277,-370.197],[1141.675,-71.124],[1217.196,220.821],[1044.029,467.699]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.713725490196,0.556862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"k":[{"s":[11.111],"t":0,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[11.111],"t":180,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":181,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".tertiary","cl":"tertiary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[0.619]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[67]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[-0.263]},"t":95,"s":[82]},{"t":180,"s":[67]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[0.913]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[639]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[-0.06]},"t":95,"s":[704]},{"t":180,"s":[639]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.12]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[527.25]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.083]},"t":95,"s":[471]},{"t":180,"s":[527.25]}],"ix":4}},"a":{"k":[{"s":[164.438,1433.781,0],"t":0,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[164.438,1433.781,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[-25,25,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2361.125,4541.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.901960784314,0.764705882353,0.423529411765,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"k":[{"s":[6],"t":0,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"s":[6],"t":180,"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}}]},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":181,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[420.5,350.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[420.5,-350.5],[-420.5,-350.5],[-420.5,350.5],[420.5,350.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/raw-sw600dp/all_set_page_bg.json b/quickstep/res/raw-sw600dp/all_set_page_bg.json index b2dd530551..f2998a038a 100644 --- a/quickstep/res/raw-sw600dp/all_set_page_bg.json +++ b/quickstep/res/raw-sw600dp/all_set_page_bg.json @@ -1 +1 @@ -{"v":"5.8.1","fr":60,"ip":0,"op":180,"w":800,"h":1280,"nm":"3Second_MainWelcomeScreen_Tablet_Portrait_V02","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[288,528,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[25,25,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"F4BA9E","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[999.832,-2238.545,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":95,"s":[999.832,-3043,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[999.832,-2238.545,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[200,200,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.956862745098,0.729411764706,0.619607843137,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"C0C9C0","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-39]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":95,"s":[-21]},{"t":180,"s":[-39]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1490]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":95,"s":[1314]},{"t":180,"s":[1490]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[2967]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":95,"s":[2770]},{"t":180,"s":[2967]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[168,168,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.752941176471,0.788235294118,0.752941176471,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.8.1","fr":60,"ip":0,"op":181,"w":701,"h":841,"nm":"SUW_WelcomeScreen_FoldableOpen_Portrait_Dynamic","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".primary","cl":"primary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[55]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.949},"o":{"x":0.167,"y":0.167},"t":0,"s":[181.172,148.425,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.038},"t":95,"s":[181.172,-68.377,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[181.172,148.425,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[21.6,21.6,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[100.594,-128.921],[118.85,-93.491],[148.984,-67.406],[148.684,-27.55],[163.244,9.552],[144.457,44.702],[140.106,84.321],[107.136,106.715],[84.872,139.773],[45.271,144.279],[10.194,163.205],[-26.964,148.792],[-66.818,149.249],[-93.023,119.218],[-128.524,101.101],[-137.771,62.332],[-160.786,29.793],[-150.957,-8.833],[-156.215,-48.341],[-129.561,-77.974],[-115.856,-115.401],[-78.484,-129.253],[-48.956,-156.023],[-9.427,-150.921],[29.159,-160.903],[61.789,-138.015]],"o":[[-100.594,128.921],[-118.85,93.491],[-148.984,67.406],[-148.684,27.55],[-163.244,-9.552],[-144.456,-44.702],[-140.106,-84.321],[-107.136,-106.715],[-84.872,-139.773],[-45.271,-144.279],[-10.194,-163.205],[26.964,-148.792],[66.818,-149.249],[93.023,-119.218],[128.524,-101.101],[137.771,-62.332],[160.786,-29.793],[150.957,8.833],[156.215,48.341],[129.561,77.974],[115.856,115.4],[78.484,129.253],[48.956,156.023],[9.427,150.921],[-29.159,160.903],[-61.789,138.015]],"v":[[975.226,761.299],[707.165,899.424],[509.8,1127.42],[208.253,1125.148],[-72.46,1235.308],[-338.41,1093.162],[-638.164,1060.25],[-807.592,810.792],[-1057.715,642.348],[-1091.808,342.727],[-1235.002,77.338],[-1125.948,-203.807],[-1129.407,-505.342],[-902.191,-703.604],[-765.123,-972.207],[-471.796,-1042.166],[-225.603,-1216.305],[66.637,-1141.935],[365.557,-1181.715],[589.761,-980.053],[872.928,-876.361],[977.734,-593.606],[1180.277,-370.197],[1141.675,-71.124],[1217.196,220.821],[1044.029,467.699]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.713725490196,0.556862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9.3,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":181,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".tertiary","cl":"tertiary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[0.619]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[67]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[-0.263]},"t":95,"s":[82]},{"t":180,"s":[67]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[0.927]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[458.803]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[-0.05]},"t":95,"s":[536.803]},{"t":180,"s":[458.803]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[707.143]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.069]},"t":95,"s":[639.643]},{"t":180,"s":[707.143]}],"ix":4}},"a":{"k":[{"s":[164.438,1433.781,0],"t":0,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[164.438,1433.781,0],"t":180,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"s":{"a":0,"k":[-30,30,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2361.125,4541.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.901960784314,0.764705882353,0.423529411765,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":181,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[350.5,420.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[420.5,-350.5],[-420.5,-350.5],[-420.5,350.5],[420.5,350.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/raw-sw720dp-land/all_set_page_bg.json b/quickstep/res/raw-sw720dp-land/all_set_page_bg.json new file mode 100644 index 0000000000..a994b0f658 --- /dev/null +++ b/quickstep/res/raw-sw720dp-land/all_set_page_bg.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":180,"w":1280,"h":800,"nm":"SUW_WelcomeScreen_Tablet_Landscape_Dynamic","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[288,540,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[25,25,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".primary","cl":"primary","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[375.832,-1006.545,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":95,"s":[375.832,-1811,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[375.832,-1006.545,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[110,110,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.956862745098,0.729411764706,0.619607843137,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".tertiary","cl":"tertiary","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[57]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":95,"s":[75]},{"t":180,"s":[57]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[2618]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":95,"s":[2442]},{"t":180,"s":[2618]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[891]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":95,"s":[694]},{"t":180,"s":[891]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[120,120,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.752941176471,0.788235294118,0.752941176471,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/raw-sw720dp/all_set_page_bg.json b/quickstep/res/raw-sw720dp/all_set_page_bg.json new file mode 100644 index 0000000000..1030ffa543 --- /dev/null +++ b/quickstep/res/raw-sw720dp/all_set_page_bg.json @@ -0,0 +1 @@ +{"v":"5.8.1","fr":60,"ip":0,"op":180,"w":800,"h":1280,"nm":"SUW_WelcomeScreen_Tablet_Portrait_Dynamic","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[288,528,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[25,25,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".primary","cl":"primary","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[999.832,-2238.545,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":95,"s":[999.832,-3043,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[999.832,-2238.545,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[200,200,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.956862745098,0.729411764706,0.619607843137,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".tertiary","cl":"tertiary","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-39]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":95,"s":[-21]},{"t":180,"s":[-39]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1490]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":95,"s":[1314]},{"t":180,"s":[1490]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[2967]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":95,"s":[2770]},{"t":180,"s":[2967]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[168,168,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.752941176471,0.788235294118,0.752941176471,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/raw/all_set_page_bg.json b/quickstep/res/raw/all_set_page_bg.json index 859d3567a2..4ae179dba5 100644 --- a/quickstep/res/raw/all_set_page_bg.json +++ b/quickstep/res/raw/all_set_page_bg.json @@ -1 +1 @@ -{"v":"5.7.8","fr":24,"ip":0,"op":72,"w":2472,"h":5352,"nm":"3Second_MAIN_Welcome","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 60","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1508,1364,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"PinkFlower","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":72,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[1505.832,1379.455,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":38,"s":[1505.832,575,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72,"s":[1505.832,1379.455,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.839215746113,0.439215716194,0.388235324037,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":288,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Ellipse_Bottom","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":38,"s":[-38]},{"t":72,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1720]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":38,"s":[1544]},{"t":72,"s":[1720]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4069]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":38,"s":[3872]},{"t":72,"s":[4069]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.882353001015,0.894118006089,0.886274988511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.8.1","fr":24,"ip":0,"op":72,"w":2472,"h":5352,"nm":"SUW_Welcome_Handheld_Dynamic","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 60","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1508,1364,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".primary","cl":"primary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":72,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[1505.832,1379.455,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":38,"s":[1505.832,575,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72,"s":[1505.832,1379.455,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":288,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".tertiary","cl":"tertiary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":38,"s":[-38]},{"t":72,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1720]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":38,"s":[1544]},{"t":72,"s":[1720]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4069]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":38,"s":[3872]},{"t":72,"s":[4069]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index a226a04359..50efb014cd 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -34,7 +34,7 @@ "በመነሻ ገጽዎ ታችኛው ረድፍ ላይ የመተግበሪያ አስተያየት ጥቆማዎችን ያግኙ" "በመነሻ ማያ ገጽዎ የተወዳጆች ረድፍ ላይ የመተግበሪያ አስተያየት ጥቆማዎችን ያግኙ" "በጣም ስራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ። በታችኛው ረድፍ ላይ ያሉ መተግበሪያዎች ወደ መነሻ ገጽዎ ይወሰዳሉ።" - "በጣም ሥራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመሥረት ይቀየራሉ። በተወዳጆች ረድፍ ውስጥ ያሉ መተግበሪያዎች ወደ የእርስዎ መነሻ ማያ ገጽ ይንቀሳቀሳሉ።" + "በጣም ሥራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመሥረት ይቀየራሉ። በተወዳጆች ረድፍ ውስጥ ያሉ መተግበሪያዎች ወደ የእርስዎ መነሻ ማያ ገፅ ይንቀሳቀሳሉ።" "የመተግበሪያ አስተያየት ጥቆማዎችን አግኝ" "አይ፣ አመሰግናለሁ" "ቅንብሮች" @@ -51,8 +51,8 @@ "ከማያ ገጹ ታችኛው ክፍል ጋር በጣም ጠጋ ብለው አለማንሸራተትዎን ያረጋግጡ።" "ከኋላ ስሜት ሰጭነት ደረጃ ለመለወጥ ወደ ቅንብሮች ይመለሱ" "ወደኋላ ለመመለስ ያንሸራትቱ" - "ወደ መጨረሻው ማያ ገጽ ለመመለስ ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።" - "ወደ መጨረሻው ማያ ገጽ ለመመለስ በ2 ጣቶች ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።" + "ወደ መጨረሻው ማያ ገፅ ለመመለስ ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።" + "ወደ መጨረሻው ማያ ገፅ ለመመለስ በ2 ጣቶች ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።" "ተመለስ" "ከማያ ገጹ የታችኛው ጫፍ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።" "ከመልቀቅዎ በፊት ለአፍታ እንዳልቆሙ ያረጋግጡ።" @@ -60,8 +60,8 @@ "የወደ መነሻ ሂድ ምልክትን አጠናቀዋል። ቀጥሎም ወደ ኋላ እንዴት መሄድ እንደሚችሉ ይወቁ።" "የወደ መነሻ ሂድ ምልክትን አጠናቀዋል።" "ወደ መነሻ ለመሄድ ያንሸራትቱ" - "ከእርስዎ ማያ ገጽ ግርጌ ላይ ወደ ላይ በጣት ጠረግ ያድርጉ። ይህ የእጅ ውዝዋዜ ሁልጊዜ ወደ መነሻ ማያ ገጽ ይወስድዎታል።" - "በ2 ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ያንሸራትቱ። ይህ የእጅ ምልክት ሁልጊዜ ወደ መነሻ ማያ ገጽ ይወስደዎታል።" + "ከእርስዎ ማያ ገፅ ግርጌ ላይ ወደ ላይ በጣት ጠረግ ያድርጉ። ይህ የእጅ ውዝዋዜ ሁልጊዜ ወደ መነሻ ማያ ገፅ ይወስድዎታል።" + "በ2 ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ያንሸራትቱ። ይህ የእጅ ምልክት ሁልጊዜ ወደ መነሻ ማያ ገፅ ይወስደዎታል።" "ወደ መነሻ ይሂዱ" "በማንኛውም ጊዜ ወደ መነሻ ማያ ገጽዎ ለመሄድ ከማያ ገጽዎ የታችኛው ክፍል ወደ ላይ ያንሸራትቱ" "ከማያ ገጹ የታችኛው ጫፍ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።" @@ -86,7 +86,7 @@ "መሣሪያ" "የስርዓት አሰሳ ቅንብሮች" "አጋራ" - "ቅጽበታዊ ገጽ እይታ" + "ቅጽበታዊ ገፅ እይታ" "ክፈል" "የተከፈለ ማያ ገጽን ለመጠቀም ሌላ መተግበሪያ መታ ያድርጉ" "የተከፈለ ማያ ገጽን ለመቀበል ሌላ መተግበሪያ ይምረጡ" diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index c424ca1c52..825a396f33 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -24,7 +24,7 @@ "কোনো শেহতীয়া বস্তু নাই" "এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিং" "আটাইবোৰ মচক" - "শেহতীয়া এপসমূহ" + "শেহতীয়া এপ্‌সমূহ" "কাৰ্য বন্ধ কৰা হ’ল" "%1$s, %2$s" "< ১ মিনিট" diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index d906ab80d4..0e959a47b3 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -88,8 +88,8 @@ "Teilen" "Screenshot" "Teilen" - "Für „Geteilter Bildschirm“ auf weitere App tippen" - "Für geteilten Bildschirm andere App auswählen" + "Für Splitscreen auf weitere App tippen" + "Für Splitscreen andere App auswählen" "Die App oder deine Organisation lässt diese Aktion nicht zu" "Tutorial zur Bedienung überspringen?" "Du findest es später auch in der %1$s App" diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml index 432352aa3a..16b56d39f8 100644 --- a/quickstep/res/values-zh-rHK/strings.xml +++ b/quickstep/res/values-zh-rHK/strings.xml @@ -30,11 +30,11 @@ "少於 1 分鐘" "今天剩餘時間:%1$s" "應用程式建議" - "您的預測應用程式" + "你的預測應用程式" "在主畫面底部取得應用程式建議" "在主畫面「我的最愛」列取得應用程式建議" - "在主畫面輕鬆存取常用的應用程式。系統會根據您的日常安排更改建議,並將底部的應用程式移到主畫面。" - "在主畫面輕鬆存取最常用的應用程式。系統會根據您的日常安排變更建議,「我的最愛」列中的應用程式會移至主畫面。" + "在主畫面輕鬆存取常用的應用程式。系統會根據你的日常安排更改建議,並將底部的應用程式移到主畫面。" + "在主畫面輕鬆存取最常用的應用程式。系統會根據你的日常安排變更建議,「我的最愛」列中的應用程式會移至主畫面。" "取得應用程式建議" "不用了,謝謝" "設定" @@ -46,8 +46,8 @@ "預測應用程式:%1$s" "請從螢幕右側或左側邊緣滑動。" "請從螢幕右側或左側邊緣往中央滑動,然後放開手指。" - "您已瞭解如何透過「由右向左滑動」手勢返回。接下來一起瞭解如何切換應用程式。" - "您已完成「返回」手勢的教學課程。" + "你已瞭解如何透過「由右向左滑動」手勢返回。接下來一起瞭解如何切換應用程式。" + "你已完成「返回」手勢的教學課程。" "滑動時,手的位置不要太接近螢幕底部。" "如要變更「返回」手勢的敏感度,請前往「設定」" "滑動即可返回" @@ -57,18 +57,18 @@ "請從螢幕底部邊緣向上滑動。" "放開手指前請勿停下來。" "請向上滑動。" - "您已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。" - "您已完成「返回主畫面」手勢的教學課程。" + "你已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。" + "你已完成「返回主畫面」手勢的教學課程。" "向上滑動即可返回主畫面" - "從螢幕底部向上滑動。這個手勢在所有畫面下都可讓您返回主畫面。" - "請用 2 隻手指從螢幕底部向上滑動。這個手勢在所有畫面下都可讓您返回主畫面。" + "從螢幕底部向上滑動。這個手勢在所有畫面下都可讓你返回主畫面。" + "請用 2 隻手指從螢幕底部向上滑動。這個手勢在所有畫面下都可讓你返回主畫面。" "返回主畫面" "只要從螢幕底部向上滑動,隨時可以返回主畫面" "請從螢幕底部邊緣向上滑動。" "請嘗試按住視窗更長時間,然後再放開。" "請向上滑動,然後停住。" - "您已學會如何使用手勢。如要關閉手勢,請前往「設定」。" - "您已完成「切換應用程式」手勢的教學課程。" + "你已學會如何使用手勢。如要關閉手勢,請前往「設定」。" + "你已完成「切換應用程式」手勢的教學課程。" "滑動即可切換應用程式" "如要切換應用程式,請從螢幕底部向上滑動並按住,然後放開。" "如要切換應用程式,請用 2 隻手指從螢幕底部向上滑動並按住,然後放開手指。" @@ -82,7 +82,7 @@ "設定完成!" "向上滑動即可前往主畫面" "輕按主按鈕即可前往主畫面" - "您可以開始使用 %1$s 了" + "你可以開始使用 %1$s 了" "裝置" "系統導覽設定" "分享" @@ -90,18 +90,18 @@ "分割" "輕按其他應用程式以使用分割螢幕" "選擇其他應用程式才能使用分割螢幕" - "應用程式或您的機構不允許此操作" + "應用程式或你的機構不允許此操作" "要略過手勢操作教學課程嗎?" - "您之後可以在「%1$s」應用程式找到這些說明" + "你之後可以在「%1$s」應用程式找到這些說明" "取消" "略過" "旋轉螢幕" "工作列教學" "將應用程式拖曳到一邊,即可同時使用 2 個應用程式" "慢慢向上滑動即可顯示工作列" - "根據您的日常安排提供應用程式建議" + "根據你的日常安排提供應用程式建議" "在「設定」中啟用手勢操作後,工作列就會自動隱藏" - "工作列助您事半功倍" + "工作列助你事半功倍" "關閉" "完成" "住宅" diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 3df5d57b55..959fea7572 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -341,9 +341,25 @@ 106dp 24dp + + 300dp + 30dp + + 72dp + 55dp + @dimen/transient_taskbar_stashed_height + @dimen/taskbar_stashed_handle_height + 8dp + + 50dp + 24dp + 12dp + 3dp + 1dp + diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml index 2c17ce8686..2b6f74945f 100644 --- a/quickstep/res/values/strings.xml +++ b/quickstep/res/values/strings.xml @@ -277,6 +277,13 @@ Taskbar hidden Navigation bar + + Always show Taskbar + + Change navigation mode + + Taskbar Divider + Move to top/left diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index f9f2175367..6c12f11bcb 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - + diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java index 9f9f2c8654..18fe30d81d 100644 --- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java +++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java @@ -120,7 +120,7 @@ public class LauncherAnimationRunner extends RemoteAnimationRunnerCompat { */ @BinderThread @Override - public void onAnimationCancelled(boolean isKeyguardOccluded) { + public void onAnimationCancelled() { postAsyncCallback(mHandler, () -> { finishExistingAnimation(); getFactory().onAnimationCancelled(); @@ -235,16 +235,12 @@ public class LauncherAnimationRunner extends RemoteAnimationRunnerCompat { RemoteAnimationTarget[] nonAppTargets, LauncherAnimationRunner.AnimationResult result); - @Override - @UiThread - default void onAnimationCancelled(boolean isKeyguardOccluded) { - onAnimationCancelled(); - } - /** * Called when the animation is cancelled. This can happen with or without * the create being called. */ - default void onAnimationCancelled() { } + @Override + @UiThread + default void onAnimationCancelled() {} } } diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 7eecb291ba..45163cb0a8 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -1841,8 +1841,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } @Override - public void onAnimationCancelled(boolean isKeyguardOccluded) { - mDelegate.onAnimationCancelled(isKeyguardOccluded); + public void onAnimationCancelled() { + mDelegate.onAnimationCancelled(); } } diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java index 3510fbef38..34316dbb1b 100644 --- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -36,6 +36,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.allapps.FloatingHeaderRow; import com.android.launcher3.allapps.FloatingHeaderView; import com.android.launcher3.anim.AlphaUpdateListener; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusIndicatorHelper; import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper; import com.android.launcher3.model.data.ItemInfo; @@ -105,12 +106,22 @@ public class PredictionRowView mActivityContext.getAppsView().getAppsStore().unregisterIconContainer(this); } } + + // Set the predicted row in All Apps' text line to 1. + if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() + || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) { + for (int i = 0; i < getChildCount(); i++) { + BubbleTextView icon = (BubbleTextView) getChildAt(i); + icon.setMaxLines(1); + } + } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getExpectedHeight(), MeasureSpec.EXACTLY)); + updateVisibility(); } @Override diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java index 4956fa1b86..726abff5da 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java @@ -21,7 +21,6 @@ import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.content.Context; -import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.model.GridBackupTable; @@ -42,10 +41,7 @@ public class HotseatRestoreHelper { context.getContentResolver(), LauncherSettings.Settings.METHOD_NEW_TRANSACTION) .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) { - InvariantDeviceProfile idp = LauncherAppState.getIDP(context); - GridBackupTable backupTable = new GridBackupTable(context, - transaction.getDb(), idp.numDatabaseHotseatIcons, idp.numColumns, - idp.numRows); + GridBackupTable backupTable = new GridBackupTable(context, transaction.getDb()); backupTable.createCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE); transaction.commit(); LauncherSettings.Settings.call(context.getContentResolver(), @@ -67,10 +63,7 @@ public class HotseatRestoreHelper { if (!tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE)) { return; } - InvariantDeviceProfile idp = LauncherAppState.getIDP(context); - GridBackupTable backupTable = new GridBackupTable(context, - transaction.getDb(), idp.numDatabaseHotseatIcons, idp.numColumns, - idp.numRows); + GridBackupTable backupTable = new GridBackupTable(context, transaction.getDb()); backupTable.restoreFromCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE, true); transaction.commit(); LauncherAppState.getInstance(context).getModel().forceReload(); diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 867e168dd2..d8458c9991 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -166,5 +166,6 @@ public class DepthController extends BaseDepthController implements StateHandler writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp); writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation=" + mIgnoreStateChangesDuringMultiWindowAnimation); + writer.println(prefix + "\tmPauseBlurs=" + mPauseBlurs); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java index 84129fdde4..926ede1edd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java @@ -23,6 +23,7 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.util.AttributeSet; +import android.view.View; import android.widget.ImageView; import androidx.annotation.NonNull; @@ -45,6 +46,7 @@ public class KeyboardQuickSwitchTaskView extends ConstraintLayout { @Nullable private ImageView mThumbnailView1; @Nullable private ImageView mThumbnailView2; + @Nullable private View mContent; public KeyboardQuickSwitchTaskView(@NonNull Context context) { this(context, null); @@ -84,7 +86,20 @@ public class KeyboardQuickSwitchTaskView extends ConstraintLayout { .getColor( R.styleable.TaskView_borderColor, DEFAULT_BORDER_COLOR), - /* invalidateViewCallback= */ KeyboardQuickSwitchTaskView.this::invalidate); + /* invalidateViewCallback= */ KeyboardQuickSwitchTaskView.this::invalidate, + /* viewScaleTargetProvider= */ new BorderAnimator.ViewScaleTargetProvider() { + @NonNull + @Override + public View getContainerView() { + return KeyboardQuickSwitchTaskView.this; + } + + @NonNull + @Override + public View getContentView() { + return mContent; + } + }); } @Override @@ -93,6 +108,7 @@ public class KeyboardQuickSwitchTaskView extends ConstraintLayout { mThumbnailView1 = findViewById(R.id.thumbnail1); mThumbnailView2 = findViewById(R.id.thumbnail2); + mContent = findViewById(R.id.content); } @NonNull diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index b74964ceae..fdef39f2eb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -93,15 +93,14 @@ public class LauncherTaskbarUIController extends TaskbarUIController { protected void init(TaskbarControllers taskbarControllers) { super.init(taskbarControllers); - mTaskbarLauncherStateController.init(mControllers, mLauncher); + mTaskbarLauncherStateController.init(mControllers, mLauncher, + mControllers.getSharedState().sysuiStateFlags); mLauncher.setTaskbarUIController(this); onLauncherResumedOrPaused(mLauncher.hasBeenResumed(), true /* fromInit */); onStashedInAppChanged(mLauncher.getDeviceProfile()); - mTaskbarLauncherStateController.updateStateForSysuiFlags( - mControllers.getSharedState().sysuiStateFlags, true /* fromInit */); mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener); // Restore the in-app display progress from before Taskbar was recreated. @@ -325,8 +324,8 @@ public class LauncherTaskbarUIController extends TaskbarUIController { } @Override - public void updateStateForSysuiFlags(int sysuiFlags, boolean skipAnim) { - mTaskbarLauncherStateController.updateStateForSysuiFlags(sysuiFlags, skipAnim); + public void updateStateForSysuiFlags(int sysuiFlags) { + mTaskbarLauncherStateController.updateStateForSysuiFlags(sysuiFlags); } @Override diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index a713ff53a7..9a9e0ba70c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -714,6 +714,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT * setup wizard, or normal 3 button nav. */ private void updateButtonLayoutSpacing() { + boolean isThreeButtonNav = mContext.isThreeButtonNav(); + DeviceProfile dp = mContext.getDeviceProfile(); Resources res = mContext.getResources(); boolean isInSetup = !mContext.isUserSetupComplete(); @@ -721,7 +723,9 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT boolean isInKidsMode = mContext.isNavBarKidsModeActive(); if (TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) { - boolean isThreeButtonNav = mContext.isThreeButtonNav(); + if (!isThreeButtonNav) { + return; + } NavButtonLayoutter navButtonLayoutter = NavButtonLayoutFactory.Companion.getUiLayoutter( @@ -803,7 +807,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mNavButtonContainer.requestLayout(); mHomeButton.setOnLongClickListener(null); - } else if (mContext.isThreeButtonNav()) { + } else if (isThreeButtonNav) { final RotateDrawable rotateDrawable = new RotateDrawable(); rotateDrawable.setDrawable(mContext.getDrawable(R.drawable.ic_sysbar_back)); rotateDrawable.setFromDegrees(0f); diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java index 5eec6a47ae..83e457140e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java @@ -30,6 +30,10 @@ import androidx.core.content.ContextCompat; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; +/** + * View to render a handle that changes color based on the background to ensure contrast. Used for + * the taskbar when stashed as well as the bubble bar when stashed. + */ public class StashedHandleView extends View { private static final long COLOR_CHANGE_DURATION = 120; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 5c53b5f844..9db03f53a6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -186,7 +186,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT); // Inflate views. - int taskbarLayout = DisplayController.isTransientTaskbar(this) + boolean phoneMode = TaskbarManager.isPhoneMode(mDeviceProfile); + int taskbarLayout = DisplayController.isTransientTaskbar(this) && !phoneMode ? R.layout.transient_taskbar : R.layout.taskbar; mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(taskbarLayout, null, false); @@ -237,7 +238,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { ? new DesktopTaskbarRecentAppsController(this) : TaskbarRecentAppsController.DEFAULT, new TaskbarEduTooltipController(this), - new KeyboardQuickSwitchController()); + new KeyboardQuickSwitchController(), + new TaskbarDividerPopupController(this)); } public void init(@NonNull TaskbarSharedState sharedState) { @@ -254,6 +256,12 @@ public class TaskbarActivityContext extends BaseTaskbarContext { sharedState.systemBarAttrsBehavior); onNavButtonsDarkIntensityChanged(sharedState.navButtonsDarkIntensity); + if (FLAG_HIDE_NAVBAR_WINDOW) { + // W/ the flag not set this entire class gets re-created, which resets the value of + // mIsDestroyed. We re-use the class for small-screen, so we explicitly have to mark + // this class as non-destroyed + mIsDestroyed = false; + } if (!mAddedWindow) { mWindowManager.addView(mDragLayer, mWindowLayoutParams); @@ -334,7 +342,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type, String title) { DeviceProfile deviceProfile = getDeviceProfile(); // Taskbar is on the logical bottom of the screen - boolean isVerticalBarLayout = TaskbarManager.isPhoneMode(deviceProfile) && + boolean isVerticalBarLayout = TaskbarManager.isPhoneButtonNavMode(this) && deviceProfile.isLandscape; int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE @@ -592,7 +600,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.voiceInteractionWindowController.setIsVoiceInteractionWindowVisible( (systemUiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0, fromInit); - mControllers.uiController.updateStateForSysuiFlags(systemUiStateFlags, fromInit); + mControllers.uiController.updateStateForSysuiFlags(systemUiStateFlags); } /** @@ -1122,4 +1130,9 @@ public class TaskbarActivityContext extends BaseTaskbarContext { public int getTaskbarAllAppsTopPadding() { return mControllers.taskbarAllAppsController.getTaskbarAllAppsTopPadding(); } + + @VisibleForTesting + public int getTaskbarAllAppsScroll() { + return mControllers.taskbarAllAppsController.getTaskbarAllAppsScroll(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt index 07cea01e91..fe365f73b2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt @@ -16,11 +16,13 @@ package com.android.launcher3.taskbar +import android.content.res.Resources import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.RectF +import com.android.launcher3.DeviceProfile import com.android.launcher3.R import com.android.launcher3.Utilities import com.android.launcher3.Utilities.mapRange @@ -61,7 +63,7 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { private val invertedLeftCornerPath: Path = Path() private val invertedRightCornerPath: Path = Path() - private val stashedHandleWidth = + private var stashedHandleWidth = context.resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width) private val stashedHandleHeight = @@ -86,6 +88,13 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { setCornerRoundness(DEFAULT_ROUNDNESS) } + fun updateStashedHandleWidth(dp: DeviceProfile, res: Resources) { + stashedHandleWidth = res.getDimensionPixelSize( + if (TaskbarManager.isPhoneMode(dp)) R.dimen.taskbar_stashed_small_screen + else R.dimen.taskbar_stashed_handle_width + ) + } + /** * Sets the roundness of the round corner above Taskbar. No effect on transient Taskkbar. * diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 8efb9b0e47..1cd6f50d33 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -60,6 +60,7 @@ public class TaskbarControllers { public final TaskbarOverlayController taskbarOverlayController; public final TaskbarEduTooltipController taskbarEduTooltipController; public final KeyboardQuickSwitchController keyboardQuickSwitchController; + public final TaskbarDividerPopupController taskbarPinningController; @Nullable private LoggableTaskbarController[] mControllersToLog = null; @Nullable private BackgroundRendererController[] mBackgroundRendererControllers = null; @@ -105,7 +106,8 @@ public class TaskbarControllers { TaskbarSpringOnStashController taskbarSpringOnStashController, TaskbarRecentAppsController taskbarRecentAppsController, TaskbarEduTooltipController taskbarEduTooltipController, - KeyboardQuickSwitchController keyboardQuickSwitchController) { + KeyboardQuickSwitchController keyboardQuickSwitchController, + TaskbarDividerPopupController taskbarPinningController) { this.taskbarActivityContext = taskbarActivityContext; this.taskbarDragController = taskbarDragController; this.navButtonController = navButtonController; @@ -130,6 +132,7 @@ public class TaskbarControllers { this.taskbarRecentAppsController = taskbarRecentAppsController; this.taskbarEduTooltipController = taskbarEduTooltipController; this.keyboardQuickSwitchController = keyboardQuickSwitchController; + this.taskbarPinningController = taskbarPinningController; } /** @@ -163,6 +166,7 @@ public class TaskbarControllers { taskbarTranslationController.init(this); taskbarEduTooltipController.init(this); keyboardQuickSwitchController.init(this); + taskbarPinningController.init(this); mControllersToLog = new LoggableTaskbarController[] { taskbarDragController, navButtonController, navbarButtonsViewController, @@ -171,7 +175,7 @@ public class TaskbarControllers { stashedHandleViewController, taskbarStashController, taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController, voiceInteractionWindowController, taskbarTranslationController, - taskbarEduTooltipController, keyboardQuickSwitchController + taskbarEduTooltipController, keyboardQuickSwitchController, taskbarPinningController }; mBackgroundRendererControllers = new BackgroundRendererController[] { taskbarDragLayerController, taskbarScrimViewController, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt new file mode 100644 index 0000000000..8dbc51af7d --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar + +import android.view.View +import com.android.launcher3.LauncherPrefs +import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING +import com.android.launcher3.taskbar.TaskbarDividerPopupView.Companion.createAndPopulate +import java.io.PrintWriter + +/** Controls taskbar pinning through a popup view. */ +class TaskbarDividerPopupController(private val context: TaskbarActivityContext) : + TaskbarControllers.LoggableTaskbarController { + + private lateinit var controllers: TaskbarControllers + private val launcherPrefs = LauncherPrefs.get(context) + + fun init(taskbarControllers: TaskbarControllers) { + controllers = taskbarControllers + } + + fun showPinningView(view: View) { + context.isTaskbarWindowFullscreen = true + + view.post { + val popupView = createAndPopulate(view, context) + popupView.requestFocus() + popupView.onCloseCallback = { + context.onPopupVisibilityChanged(false) + if (launcherPrefs.get(TASKBAR_PINNING)) { + animateTransientToPersistentTaskBar() + } else { + animatePersistentToTransientTaskbar() + } + } + popupView.changePreference = { + launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING)) + } + context.onPopupVisibilityChanged(true) + popupView.show() + } + } + + // TODO(b/265436799): provide animation/transition from transient taskbar to persistent one + private fun animateTransientToPersistentTaskBar() {} + + // TODO(b/265436799): provide animation/transition from persistent taskbar to transient one + private fun animatePersistentToTransientTaskbar() {} + + override fun dumpLogs(prefix: String, pw: PrintWriter) { + pw.println(prefix + "TaskbarPinningController:") + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt new file mode 100644 index 0000000000..2000d984c4 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Rect +import android.util.AttributeSet +import android.view.Gravity +import android.view.MotionEvent +import android.view.View +import android.widget.LinearLayout +import android.widget.Switch +import androidx.core.view.postDelayed +import com.android.launcher3.R +import com.android.launcher3.popup.ArrowPopup +import com.android.launcher3.popup.RoundedArrowDrawable +import com.android.launcher3.util.DisplayController +import com.android.launcher3.util.Themes + +/** Popup view with arrow for taskbar pinning */ +class TaskbarDividerPopupView +@JvmOverloads +constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, +) : ArrowPopup(context, attrs, defStyleAttr) { + companion object { + private const val TAG = "TaskbarDividerPopupView" + private const val DIVIDER_POPUP_CLOSING_DELAY = 500L + + @JvmStatic + fun createAndPopulate( + view: View, + taskbarActivityContext: TaskbarActivityContext, + ): TaskbarDividerPopupView<*> { + val taskMenuViewWithArrow = + taskbarActivityContext.layoutInflater.inflate( + R.layout.taskbar_divider_popup_menu, + taskbarActivityContext.dragLayer, + false + ) as TaskbarDividerPopupView<*> + + return taskMenuViewWithArrow.populateForView(view) + } + } + private lateinit var dividerView: View + + private val menuWidth = + context.resources.getDimensionPixelSize(R.dimen.taskbar_pinning_popup_menu_width) + private val popupCornerRadius = Themes.getDialogCornerRadius(context) + private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width) + private val arrowHeight = resources.getDimension(R.dimen.popup_arrow_height) + private val arrowPointRadius = resources.getDimension(R.dimen.popup_arrow_corner_radius) + + private var alwaysShowTaskbarOn = !DisplayController.isTransientTaskbar(context) + private var didPreferenceChange = false + + /** Callback invoked when the pinning popup view is closing. */ + var onCloseCallback: () -> Unit = {} + + /** + * Callback invoked when the user preference changes in popup view. Preference change will be + * based upon current value stored in [LauncherPrefs] for `TASKBAR_PINNING` + */ + var changePreference: () -> Unit = {} + + init { + // This synchronizes the arrow and menu to open at the same time + mOpenChildFadeStartDelay = mOpenFadeStartDelay + mOpenChildFadeDuration = mOpenFadeDuration + mCloseFadeStartDelay = mCloseChildFadeStartDelay + mCloseFadeDuration = mCloseChildFadeDuration + } + + override fun isOfType(type: Int): Boolean = type and TYPE_TASKBAR_PINNING_POPUP != 0 + + override fun getTargetObjectLocation(outPos: Rect) { + popupContainer.getDescendantRectRelativeToSelf(dividerView, outPos) + } + + @SuppressLint("UseSwitchCompatOrMaterialCode") + override fun onFinishInflate() { + super.onFinishInflate() + val taskbarSwitchOption = findViewById(R.id.taskbar_switch_option) + val alwaysShowTaskbarSwitch = findViewById(R.id.taskbar_pinning_switch) + alwaysShowTaskbarSwitch.isChecked = alwaysShowTaskbarOn + taskbarSwitchOption.setOnClickListener { + alwaysShowTaskbarSwitch.isClickable = true + alwaysShowTaskbarSwitch.isChecked = !alwaysShowTaskbarOn + onClickAlwaysShowTaskbarSwitchOption() + } + } + + /** Orient object as usual and then center object horizontally. */ + override fun orientAboutObject() { + super.orientAboutObject() + x = mTempRect.centerX() - menuWidth / 2f + } + + override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean { + if (ev?.action == MotionEvent.ACTION_DOWN) { + if (!popupContainer.isEventOverView(this, ev)) { + close(true) + } + } else if (popupContainer.isEventOverView(dividerView, ev)) { + return true + } + return false + } + + private fun populateForView(view: View): TaskbarDividerPopupView<*> { + dividerView = view + return this + } + + override fun addArrow() { + super.addArrow() + // Change arrow location to the middle of popup. + mArrow.x = (dividerView.x + dividerView.width / 2) - (mArrowWidth / 2) + } + + override fun updateArrowColor() { + if (!Gravity.isVertical(mGravity)) { + mArrow.background = + RoundedArrowDrawable( + arrowWidth, + arrowHeight, + arrowPointRadius, + popupCornerRadius, + measuredWidth.toFloat(), + measuredHeight.toFloat(), + (measuredWidth - arrowWidth) / 2, // arrowOffsetX + 0f, // arrowOffsetY + false, // isPointingUp + true, // leftAligned + Themes.getAttrColor(context, R.attr.popupColorPrimary), + ) + elevation = mElevation + mArrow.elevation = mElevation + } + } + + override fun closeComplete() { + if (didPreferenceChange) { + onCloseCallback() + } + super.closeComplete() + } + + private fun onClickAlwaysShowTaskbarSwitchOption() { + didPreferenceChange = true + changePreference() + // Allow switch animation to finish and then close the popup. + postDelayed(DIVIDER_POPUP_CLOSING_DELAY) { close(true) } + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index c53460d104..7681fe0e96 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -71,7 +71,7 @@ public class TaskbarDragLayer extends BaseDragLayer { public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) { mControllerCallbacks = callbacks; - + mBackgroundRenderer.updateStashedHandleWidth(mActivity.getDeviceProfile(), getResources()); recreateControllers(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt index 4373a88802..2c686b8a13 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt @@ -15,8 +15,6 @@ */ package com.android.launcher3.taskbar -import android.graphics.PorterDuff.Mode.SRC_ATOP -import android.graphics.PorterDuffColorFilter import android.os.Bundle import android.view.View import android.view.View.GONE @@ -27,14 +25,13 @@ import android.view.accessibility.AccessibilityNodeInfo import androidx.annotation.IntDef import androidx.annotation.LayoutRes import com.airbnb.lottie.LottieAnimationView -import com.airbnb.lottie.LottieProperty.COLOR_FILTER -import com.airbnb.lottie.model.KeyPath import com.android.launcher3.R import com.android.launcher3.Utilities import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController import com.android.launcher3.util.DisplayController import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP +import com.android.quickstep.util.LottieAnimationColorUtils import java.io.PrintWriter /** First EDU step for swiping up to show transient Taskbar. */ @@ -239,11 +236,5 @@ private fun LottieAnimationView.supportLightTheme() { return } - addLottieOnCompositionLoadedListener { - DARK_TO_LIGHT_COLORS.forEach { (key, color) -> - addValueCallback(KeyPath("**", key, "**"), COLOR_FILTER) { - PorterDuffColorFilter(context.getColor(color), SRC_ATOP) - } - } - } + LottieAnimationColorUtils.updateColors(this, DARK_TO_LIGHT_COLORS, context.theme) } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index fcb20423fa..c029097b71 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -21,6 +21,7 @@ import android.os.Binder import android.os.IBinder import android.view.InsetsFrameProvider import android.view.InsetsFrameProvider.SOURCE_DISPLAY +import android.view.InsetsSource.FLAG_SUPPRESS_SCRIM import android.view.ViewTreeObserver import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION @@ -86,7 +87,8 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas if (context.isGestureNav) { windowLayoutParams.providedInsets = arrayOf( - InsetsFrameProvider(insetsOwner, 0, navigationBars()), + InsetsFrameProvider(insetsOwner, 0, navigationBars()) + .setFlags(FLAG_SUPPRESS_SCRIM, FLAG_SUPPRESS_SCRIM), InsetsFrameProvider(insetsOwner, 0, tappableElement()), InsetsFrameProvider(insetsOwner, 0, mandatorySystemGestures()), InsetsFrameProvider(insetsOwner, INDEX_LEFT, systemGestures()) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index c9e7df45a1..59b5e743f6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -210,7 +210,9 @@ public class TaskbarLauncherStateController { } }; - public void init(TaskbarControllers controllers, QuickstepLauncher launcher) { + /** Initializes the controller instance, and applies the initial state immediately. */ + public void init(TaskbarControllers controllers, QuickstepLauncher launcher, + int sysuiStateFlags) { mCanSyncViews = false; mControllers = controllers; @@ -229,6 +231,8 @@ public class TaskbarLauncherStateController { mLauncher.getStateManager().addStateListener(mStateListener); mLauncherState = launcher.getStateManager().getState(); + updateStateForSysuiFlags(sysuiStateFlags, /*applyState*/ false); + applyState(0); mCanSyncViews = true; @@ -298,7 +302,11 @@ public class TaskbarLauncherStateController { } /** SysUI flags updated, see QuickStepContract.SYSUI_STATE_* values. */ - public void updateStateForSysuiFlags(int systemUiStateFlags, boolean skipAnim) { + public void updateStateForSysuiFlags(int systemUiStateFlags) { + updateStateForSysuiFlags(systemUiStateFlags, /* applyState */ true); + } + + private void updateStateForSysuiFlags(int systemUiStateFlags, boolean applyState) { final boolean prevIsAwake = hasAnyFlag(FLAG_AWAKE); final boolean currIsAwake = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_AWAKE); @@ -322,9 +330,7 @@ public class TaskbarLauncherStateController { || (systemUiStateFlags & SYSUI_STATE_WAKEFULNESS_MASK) != WAKEFULNESS_AWAKE; updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden); - if (skipAnim) { - applyState(0); - } else { + if (applyState) { applyState(); } } @@ -361,10 +367,6 @@ public class TaskbarLauncherStateController { applyState(duration, true); } - public Animator applyState(boolean start) { - return applyState(mControllers.taskbarStashController.getStashDuration(), start); - } - public Animator applyState(long duration, boolean start) { if (mControllers.taskbarActivityContext.isDestroyed()) { return null; @@ -420,7 +422,7 @@ public class TaskbarLauncherStateController { } } - if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE | FLAG_AWAKE)) { + if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE)) { animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { @@ -642,14 +644,8 @@ public class TaskbarLauncherStateController { long resetDuration = mControllers.taskbarStashController.isInApp() ? duration : duration / 2; - boolean shouldReset = - mControllers.taskbarTranslationController.shouldResetBackToZero(resetDuration); - boolean goingToLauncher = isAnimatingToLauncher(); - boolean isNormalState = mLauncherState == LauncherState.NORMAL; - // Taskbar should always reset when animating to launcher in normal state to ensure there - // is no jump during the handoff to the hotseat. - if ((goingToLauncher && isNormalState) - || (shouldReset && (goingToLauncher || isNormalState))) { + if (!mControllers.taskbarTranslationController.willAnimateToZeroBefore(resetDuration) + && (isAnimatingToLauncher() || mLauncherState == LauncherState.NORMAL)) { animatorSet.play(mControllers.taskbarTranslationController .createAnimToResetTranslation(resetDuration)); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index 3d8bf9ea63..738ff87744 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -20,6 +20,8 @@ import static android.content.pm.PackageManager.FEATURE_PC; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; +import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING; +import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.DisplayController.TASKBAR_NOT_DESTROYED_TAG; @@ -32,6 +34,7 @@ import android.content.ComponentCallbacks; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.hardware.display.DisplayManager; @@ -48,6 +51,7 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider; @@ -133,6 +137,13 @@ public class TaskbarManager { private final SimpleBroadcastReceiver mTaskbarBroadcastReceiver = new SimpleBroadcastReceiver(this::showTaskbarFromBroadcast); + private final SharedPreferences.OnSharedPreferenceChangeListener + mTaskbarPinningPreferenceChangeListener = (sharedPreferences, key) -> { + if (TASKBAR_PINNING_KEY.equals(key)) { + recreateTaskbar(); + } + }; + @SuppressLint("WrongConstant") public TaskbarManager(TouchInteractionService service) { mDisplayController = DisplayController.INSTANCE.get(service); @@ -168,9 +179,14 @@ public class TaskbarManager { DeviceProfile oldDp = mTaskbarActivityContext.getDeviceProfile(); boolean isOrientationChange = (configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0; + + int newOrientation = newConfig.windowConfiguration.getRotation(); + int oldOrientation = mOldConfig.windowConfiguration.getRotation(); int oldWidth = isOrientationChange ? oldDp.heightPx : oldDp.widthPx; int oldHeight = isOrientationChange ? oldDp.widthPx : oldDp.heightPx; - if (dp.widthPx == oldWidth && dp.heightPx == oldHeight) { + + if ((dp.widthPx == oldWidth && dp.heightPx == oldHeight) + || (newOrientation == oldOrientation)) { configDiffForRecreate &= ~ActivityInfo.CONFIG_SCREEN_SIZE; } } @@ -244,6 +260,8 @@ public class TaskbarManager { private void destroyExistingTaskbar() { debugWhyTaskbarNotDestroyed("destroyExistingTaskbar: " + mTaskbarActivityContext); if (mTaskbarActivityContext != null) { + LauncherPrefs.get(mContext).removeListener(mTaskbarPinningPreferenceChangeListener, + TASKBAR_PINNING); mTaskbarActivityContext.onDestroy(); if (!FLAG_HIDE_NAVBAR_WINDOW) { mTaskbarActivityContext = null; @@ -380,6 +398,10 @@ public class TaskbarManager { mTaskbarActivityContext.setUIController( createTaskbarUIControllerForActivity(mActivity)); } + + // We to wait until user unlocks the device to attach listener. + LauncherPrefs.get(mContext).addListener(mTaskbarPinningPreferenceChangeListener, + TASKBAR_PINNING); } public void onSystemUiFlagsChanged(int systemUiStateFlags) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java index 90fcd37d2e..5abeac7654 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java @@ -137,6 +137,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba if (folder != null) { folder.iterateOverItems(op); } + mControllers.taskbarAllAppsController.updateNotificationDots(updatedDots); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 69ea9fd03a..1d90a43111 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -18,11 +18,12 @@ package com.android.launcher3.taskbar; import static android.view.HapticFeedbackConstants.LONG_PRESS; import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS; +import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY; import static com.android.launcher3.anim.Interpolators.EMPHASIZED; import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; -import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR; +import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_PINNING; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE; @@ -324,7 +325,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // that taskbar unstashes when going to 3 button mode (supportsVisualStashing() false). boolean isManuallyStashedInApp = supportsVisualStashing() && !isTransientTaskbar - && !FORCE_PERSISTENT_TASKBAR.get() + && !ENABLE_TASKBAR_PINNING.get() && mPrefs.getBoolean(SHARED_PREFS_STASHED_KEY, DEFAULT_STASHED_PREF); boolean isInSetup = !mActivity.isUserSetupComplete() || setupUIVisible; updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp); @@ -353,7 +354,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Returns whether the user can manually stash the taskbar based on the current device state. */ protected boolean supportsManualStashing() { - if (FORCE_PERSISTENT_TASKBAR.get()) { + if (ENABLE_TASKBAR_PINNING.get() && mPrefs.getBoolean(TASKBAR_PINNING_KEY, false)) { return false; } return supportsVisualStashing() diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java index 4b18bb6556..065d1117c8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java @@ -54,7 +54,6 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable private boolean mHasSprungOnceThisGesture; private @Nullable ValueAnimator mSpringBounce; private boolean mGestureEnded; - private boolean mGestureInProgress; private boolean mAnimationToHomeRunning; private final boolean mIsTransientTaskbar; @@ -124,7 +123,6 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable private void reset() { mGestureEnded = false; - mGestureInProgress = false; mHasSprungOnceThisGesture = false; } @@ -136,24 +134,18 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable } /** - * Returns {@code true} if we should reset the animation back to zero. - * - * Returns {@code false} if there is a gesture in progress, or if we are already animating - * to 0 within the specified duration. + * Returns true if we will animate to zero before the input duration. */ - public boolean shouldResetBackToZero(long duration) { - if (mGestureInProgress) { - return false; - } + public boolean willAnimateToZeroBefore(long duration) { if (mSpringBounce != null && mSpringBounce.isRunning()) { long springDuration = mSpringBounce.getDuration(); long current = mSpringBounce.getCurrentPlayTime(); - return (springDuration - current >= duration); + return (springDuration - current < duration); } if (mTranslationYForSwipe.isAnimatingToValue(0)) { - return mTranslationYForSwipe.getRemainingTime() >= duration; + return mTranslationYForSwipe.getRemainingTime() < duration; } - return true; + return false; } /** @@ -196,7 +188,6 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable mAnimationToHomeRunning = false; cancelSpringIfExists(); reset(); - mGestureInProgress = true; } /** * Called when there is movement to move the taskbar. @@ -220,7 +211,6 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable mGestureEnded = true; startSpring(); } - mGestureInProgress = false; } } @@ -232,7 +222,6 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable pw.println(prefix + "\tmHasSprungOnceThisGesture=" + mHasSprungOnceThisGesture); pw.println(prefix + "\tmAnimationToHomeRunning=" + mAnimationToHomeRunning); pw.println(prefix + "\tmGestureEnded=" + mGestureEnded); - pw.println(prefix + "\tmGestureInProgress=" + mGestureInProgress); pw.println(prefix + "\tmSpringBounce is running=" + (mSpringBounce != null && mSpringBounce.isRunning())); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 1435cb0996..f3e2ee2e9d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -127,7 +127,7 @@ public class TaskbarUIController { /** * SysUI flags updated, see QuickStepContract.SYSUI_STATE_* values. */ - public void updateStateForSysuiFlags(int sysuiFlags, boolean skipAnim){ + public void updateStateForSysuiFlags(int sysuiFlags) { } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index a3e681403a..f099e0636f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -114,7 +114,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar mActivityContext = ActivityContext.lookupContext(context); mIconLayoutBounds = mActivityContext.getTransientTaskbarBounds(); Resources resources = getResources(); - boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext); + boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext) + && !TaskbarManager.isPhoneMode(mActivityContext.getDeviceProfile()); mIsRtl = Utilities.isRtl(resources); mTransientTaskbarMinWidth = mContext.getResources().getDimension( R.dimen.transient_taskbar_min_width); @@ -217,7 +218,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar mAllAppsButton.setOnClickListener(mControllerCallbacks.getAllAppsButtonClickListener()); } if (mTaskbarDivider != null) { - //TODO(b/265434705): set long press listener + mTaskbarDivider.setOnLongClickListener( + mControllerCallbacks.getTaskbarDividerLongClickListener()); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 6eb409e35d..ec3d1bcc0a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -641,6 +641,13 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar }; } + public View.OnLongClickListener getTaskbarDividerLongClickListener() { + return v -> { + mControllers.taskbarPinningController.showPinningView(v); + return true; + }; + } + public View.OnLongClickListener getIconOnLongClickListener() { return mControllers.taskbarDragController::startDragOnLongClick; } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java index 4a95a8f718..4266c71d3e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java @@ -24,8 +24,10 @@ import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.taskbar.TaskbarControllers; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; +import com.android.launcher3.util.PackageUserKey; import java.util.List; +import java.util.function.Predicate; /** * Handles the all apps overlay window initialization, updates, and its data. @@ -91,6 +93,13 @@ public final class TaskbarAllAppsController { } } + /** Updates the current notification dots. */ + public void updateNotificationDots(Predicate updatedDots) { + if (mAppsView != null) { + mAppsView.getAppsStore().updateNotificationDots(updatedDots); + } + } + /** Opens the {@link TaskbarAllAppsContainerView} in a new window. */ public void show() { show(true); @@ -135,10 +144,15 @@ public final class TaskbarAllAppsController { overlayContext.getDragController().setDisallowLongClick(mDisallowLongClick); } - @VisibleForTesting public int getTaskbarAllAppsTopPadding() { // Allow null-pointer since this should only be null if the apps view is not showing. return mAppsView.getActiveRecyclerView().getClipBounds().top; } + + @VisibleForTesting + public int getTaskbarAllAppsScroll() { + // Allow null-pointer since this should only be null if the apps view is not showing. + return mAppsView.getActiveRecyclerView().computeVerticalScrollOffset(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java index d69769a8a4..f0d28dfd05 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java @@ -71,13 +71,6 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView mBubbles = new ArrayMap<>(); + + private static final Executor BUBBLE_STATE_EXECUTOR = Executors.newSingleThreadExecutor( + new SimpleThreadFactory("BubbleStateUpdates-", THREAD_PRIORITY_BACKGROUND)); + private final Executor mMainExecutor; + private final LauncherApps mLauncherApps; + private final BubbleIconFactory mIconFactory; + + private BubbleBarBubble mSelectedBubble; + + private BubbleBarViewController mBubbleBarViewController; + private BubbleStashController mBubbleStashController; + private BubbleStashedHandleViewController mBubbleStashedHandleViewController; + + /** + * Similar to {@link BubbleBarUpdate} but rather than {@link BubbleInfo}s it uses + * {@link BubbleBarBubble}s so that it can be used to update the views. + */ + private static class BubbleBarViewUpdate { + boolean expandedChanged; + boolean expanded; + String selectedBubbleKey; + String suppressedBubbleKey; + String unsuppressedBubbleKey; + List removedBubbles; + List bubbleKeysInOrder; + + // These need to be loaded in the background + BubbleBarBubble addedBubble; + BubbleBarBubble updatedBubble; + List currentBubbles; + + BubbleBarViewUpdate(BubbleBarUpdate update) { + expandedChanged = update.expandedChanged; + expanded = update.expanded; + selectedBubbleKey = update.selectedBubbleKey; + suppressedBubbleKey = update.suppressedBubbleKey; + unsuppressedBubbleKey = update.unsupressedBubbleKey; + removedBubbles = update.removedBubbles; + bubbleKeysInOrder = update.bubbleKeysInOrder; + } + } + + public BubbleBarController(Context context, BubbleBarView bubbleView) { + mContext = context; + mBarView = bubbleView; // Need the view for inflating bubble views. + + // TODO: register the listener with SysUiProxu + mMainExecutor = MAIN_EXECUTOR; + mLauncherApps = context.getSystemService(LauncherApps.class); + mIconFactory = new BubbleIconFactory(context, + context.getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size), + context.getResources().getDimensionPixelSize(R.dimen.bubblebar_badge_size), + context.getResources().getColor(R.color.important_conversation), + context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.importance_ring_stroke_width)); + } + + public void onDestroy() { + // TODO: unregister the listener with SysUiProxy + } + + public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) { + mBubbleBarViewController = bubbleControllers.bubbleBarViewController; + mBubbleStashController = bubbleControllers.bubbleStashController; + mBubbleStashedHandleViewController = bubbleControllers.bubbleStashedHandleViewController; + + bubbleControllers.runAfterInit(() -> { + mBubbleBarViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED); + mBubbleStashedHandleViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED); + }); + } + + /** + * Updates the bubble bar, handle bar, and stash controllers based on sysui state flags. + */ + public void updateStateForSysuiFlags(int flags) { + boolean hideBubbleBar = (flags & MASK_HIDE_BUBBLE_BAR) != 0; + mBubbleBarViewController.setHiddenForSysui(hideBubbleBar); + + boolean hideHandleView = (flags & MASK_HIDE_HANDLE_VIEW) != 0; + mBubbleStashedHandleViewController.setHiddenForSysui(hideHandleView); + + boolean sysuiLocked = (flags & MASK_SYSUI_LOCKED) != 0; + mBubbleStashController.onSysuiLockedStateChange(sysuiLocked); + } + + // + // Bubble data changes + // + + @BinderThread + @Override + public void onBubbleStateChange(Bundle bundle) { + bundle.setClassLoader(BubbleBarUpdate.class.getClassLoader()); + BubbleBarUpdate update = bundle.getParcelable("update", BubbleBarUpdate.class); + BubbleBarViewUpdate viewUpdate = new BubbleBarViewUpdate(update); + if (update.addedBubble != null + || update.updatedBubble != null + || !update.currentBubbleList.isEmpty()) { + // We have bubbles to load + BUBBLE_STATE_EXECUTOR.execute(() -> { + if (update.addedBubble != null) { + viewUpdate.addedBubble = populateBubble(update.addedBubble, mContext, mBarView); + } + if (update.updatedBubble != null) { + viewUpdate.updatedBubble = + populateBubble(update.updatedBubble, mContext, mBarView); + } + if (update.currentBubbleList != null && !update.currentBubbleList.isEmpty()) { + List currentBubbles = new ArrayList<>(); + for (int i = 0; i < update.currentBubbleList.size(); i++) { + BubbleBarBubble b = + populateBubble(update.currentBubbleList.get(i), mContext, mBarView); + currentBubbles.add(b); + } + viewUpdate.currentBubbles = currentBubbles; + } + mMainExecutor.execute(() -> applyViewChanges(viewUpdate)); + }); + } else { + // No bubbles to load, immediately apply the changes. + BUBBLE_STATE_EXECUTOR.execute( + () -> mMainExecutor.execute(() -> applyViewChanges(viewUpdate))); + } + } + + private void applyViewChanges(BubbleBarViewUpdate update) { + final boolean isCollapsed = (update.expandedChanged && !update.expanded) + || (!update.expandedChanged && !mBubbleBarViewController.isExpanded()); + BubbleBarBubble bubbleToSelect = null; + if (!update.removedBubbles.isEmpty()) { + for (int i = 0; i < update.removedBubbles.size(); i++) { + RemovedBubble removedBubble = update.removedBubbles.get(i); + BubbleBarBubble bubble = mBubbles.remove(removedBubble.getKey()); + if (bubble != null) { + mBubbleBarViewController.removeBubble(bubble); + } else { + Log.w(TAG, "trying to remove bubble that doesn't exist: " + + removedBubble.getKey()); + } + } + } + if (update.addedBubble != null) { + mBubbles.put(update.addedBubble.getKey(), update.addedBubble); + mBubbleBarViewController.addBubble(update.addedBubble); + if (isCollapsed) { + // If we're collapsed, the most recently added bubble will be selected. + bubbleToSelect = update.addedBubble; + } + + } + if (update.currentBubbles != null && !update.currentBubbles.isEmpty()) { + // Iterate in reverse because new bubbles are added in front and the list is in order. + for (int i = update.currentBubbles.size() - 1; i >= 0; i--) { + BubbleBarBubble bubble = update.currentBubbles.get(i); + if (bubble != null) { + mBubbles.put(bubble.getKey(), bubble); + mBubbleBarViewController.addBubble(bubble); + if (isCollapsed) { + // If we're collapsed, the most recently added bubble will be selected. + bubbleToSelect = bubble; + } + } else { + Log.w(TAG, "trying to add bubble but null after loading! " + + update.addedBubble.getKey()); + } + } + } + + // Adds and removals have happened, update visibility before any other visual changes. + mBubbleBarViewController.setHiddenForBubbles(mBubbles.isEmpty()); + mBubbleStashedHandleViewController.setHiddenForBubbles(mBubbles.isEmpty()); + + if (update.updatedBubble != null) { + // TODO: (b/269670235) handle updates: + // (1) if content / icons change -- requires reload & add back in place + // (2) if showing update dot changes -- tell the view to hide / show the dot + } + if (update.bubbleKeysInOrder != null && !update.bubbleKeysInOrder.isEmpty()) { + // Create the new list + List newOrder = update.bubbleKeysInOrder.stream() + .map(mBubbles::get).filter(Objects::nonNull).toList(); + if (!newOrder.isEmpty()) { + mBubbleBarViewController.reorderBubbles(newOrder); + } + } + if (update.suppressedBubbleKey != null) { + // TODO: (b/273316505) handle suppression + } + if (update.unsuppressedBubbleKey != null) { + // TODO: (b/273316505) handle suppression + } + if (update.selectedBubbleKey != null) { + if (mSelectedBubble != null + && !update.selectedBubbleKey.equals(mSelectedBubble.getKey())) { + BubbleBarBubble newlySelected = mBubbles.get(update.selectedBubbleKey); + if (newlySelected != null) { + bubbleToSelect = newlySelected; + } else { + Log.w(TAG, "trying to select bubble that doesn't exist:" + + update.selectedBubbleKey); + } + } + } + if (bubbleToSelect != null) { + setSelectedBubble(bubbleToSelect); + } + if (update.expandedChanged) { + if (update.expanded != mBubbleBarViewController.isExpanded()) { + mBubbleBarViewController.setExpandedFromSysui(update.expanded); + } else { + Log.w(TAG, "expansion was changed but is the same"); + } + } + } + + /** + * Sets the bubble that should be selected. This notifies the views, it does not notify + * WMShell that the selection has changed, that should go through + * {@link SystemUiProxy#showBubble}. + */ + public void setSelectedBubble(BubbleBarBubble b) { + if (!Objects.equals(b, mSelectedBubble)) { + if (DEBUG) Log.w(TAG, "selectingBubble: " + b.getKey()); + mSelectedBubble = b; + mBubbleBarViewController.updateSelectedBubble(mSelectedBubble); + } + } + + /** + * Returns the selected bubble or null if no bubble is selected. + */ + @Nullable + public String getSelectedBubbleKey() { + if (mSelectedBubble != null) { + return mSelectedBubble.getKey(); + } + return null; + } + + // + // Loading data for the bubbles + // + + @Nullable + private BubbleBarBubble populateBubble(BubbleInfo b, Context context, BubbleBarView bbv) { + String appName; + Bitmap badgeBitmap; + Bitmap bubbleBitmap; + Path dotPath; + int dotColor; + + boolean isImportantConvo = false; // TODO: (b/269671451) needs to be added to BubbleInfo + + ShortcutRequest.QueryResult result = new ShortcutRequest(context, + new UserHandle(b.getUserId())) + .forPackage(b.getPackageName(), b.getShortcutId()) + .query(FLAG_MATCH_DYNAMIC + | FLAG_MATCH_PINNED_BY_ANY_LAUNCHER + | FLAG_MATCH_CACHED + | FLAG_GET_PERSONS_DATA); + + ShortcutInfo shortcutInfo = result.size() > 0 ? result.get(0) : null; + if (shortcutInfo == null) { + Log.w(TAG, "No shortcutInfo found for bubble: " + b.getKey() + + " with shortcutId: " + b.getShortcutId()); + } + + ApplicationInfo appInfo; + try { + appInfo = mLauncherApps.getApplicationInfo( + b.getPackageName(), + 0, + new UserHandle(b.getUserId())); + } catch (PackageManager.NameNotFoundException e) { + // If we can't find package... don't think we should show the bubble. + Log.w(TAG, "Unable to find packageName: " + b.getPackageName()); + return null; + } + if (appInfo == null) { + Log.w(TAG, "Unable to find appInfo: " + b.getPackageName()); + return null; + } + PackageManager pm = context.getPackageManager(); + appName = String.valueOf(appInfo.loadLabel(pm)); + Drawable appIcon = appInfo.loadUnbadgedIcon(pm); + Drawable badgedIcon = pm.getUserBadgedIcon(appIcon, new UserHandle(b.getUserId())); + + // Badged bubble image + Drawable bubbleDrawable = mIconFactory.getBubbleDrawable(context, shortcutInfo, + b.getIcon()); + if (bubbleDrawable == null) { + // Default to app icon + bubbleDrawable = appIcon; + } + + BitmapInfo badgeBitmapInfo = mIconFactory.getBadgeBitmap(badgedIcon, isImportantConvo); + badgeBitmap = badgeBitmapInfo.icon; + + float[] bubbleBitmapScale = new float[1]; + bubbleBitmap = mIconFactory.getBubbleBitmap(bubbleDrawable, bubbleBitmapScale); + + // Dot color & placement + Path iconPath = PathParser.createPathFromPathData( + context.getResources().getString( + com.android.internal.R.string.config_icon_mask)); + Matrix matrix = new Matrix(); + float scale = bubbleBitmapScale[0]; + float radius = BubbleView.DEFAULT_PATH_SIZE / 2f; + matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */, + radius /* pivot y */); + iconPath.transform(matrix); + dotPath = iconPath; + dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color, + Color.WHITE, WHITE_SCRIM_ALPHA); + + + LayoutInflater inflater = LayoutInflater.from(context); + BubbleView bubbleView = (BubbleView) inflater.inflate( + R.layout.bubblebar_item_view, bbv, false /* attachToRoot */); + + BubbleBarBubble bubble = new BubbleBarBubble(b, bubbleView, + badgeBitmap, bubbleBitmap, dotColor, dotPath, appName); + bubbleView.setBubble(bubble); + return bubble; + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java new file mode 100644 index 0000000000..07de3b8c15 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.bubbles; + +import android.annotation.Nullable; +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.android.launcher3.R; +import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.views.ActivityContext; + +import java.util.List; + +/** + * The view that holds all the bubble views. Modifying this view should happen through + * {@link BubbleBarViewController}. Updates to the bubbles themselves (adds, removes, updates, + * selection) should happen through {@link BubbleBarController} which is the source of truth + * for state information about the bubbles. + *

+ * The bubble bar has a couple of visual states: + * - stashed as a handle + * - unstashed but collapsed, in this state the bar is showing but the bubbles are stacked within it + * - unstashed and expanded, in this state the bar is showing and the bubbles are shown in a row + * with one of the bubbles being selected. Additionally, WMShell will display the expanded bubble + * view above the bar. + *

+ * The bubble bar has some behavior related to taskbar: + * - When taskbar is unstashed, bubble bar will also become unstashed (but in its "collapsed" + * state) + * - When taskbar is stashed, bubble bar will also become stashed (unless bubble bar is in its + * "expanded" state) + * - When bubble bar is in its "expanded" state, taskbar becomes stashed + *

+ * If there are no bubbles, the bubble bar and bubble stashed handle are not shown. Additionally + * the bubble bar and stashed handle are not shown on lockscreen. + *

+ * When taskbar is in persistent or 3 button nav mode, the bubble bar is not available, and instead + * the bubbles are shown fully by WMShell in their floating mode. + */ +public class BubbleBarView extends FrameLayout { + + private static final String TAG = BubbleBarView.class.getSimpleName(); + + // TODO: (b/273594744) calculate the amount of space we have and base the max on that + // if it's smaller than 5. + private static final int MAX_BUBBLES = 5; + + private final TaskbarActivityContext mActivityContext; + private final BubbleBarBackground mBubbleBarBackground; + + // The current bounds of all the bubble bar. + private final Rect mBubbleBarBounds = new Rect(); + // The amount the bubbles overlap when they are stacked in the bubble bar + private final float mIconOverlapAmount; + // The spacing between the bubbles when they are expanded in the bubble bar + private final float mIconSpacing; + // The size of a bubble in the bar + private final float mIconSize; + // The elevation of the bubbles within the bar + private final float mBubbleElevation; + + // Whether the bar is expanded (i.e. the bubble activity is being displayed). + private boolean mIsBarExpanded = false; + // The currently selected bubble view. + private BubbleView mSelectedBubbleView; + // The click listener when the bubble bar is collapsed. + private View.OnClickListener mOnClickListener; + + private final Rect mTempRect = new Rect(); + + // We don't reorder the bubbles when they are expanded as it could be jarring for the user + // this runnable will be populated with any reordering of the bubbles that should be applied + // once they are collapsed. + @Nullable + private Runnable mReorderRunnable; + + public BubbleBarView(Context context) { + this(context, null); + } + + public BubbleBarView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BubbleBarView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public BubbleBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + mActivityContext = ActivityContext.lookupContext(context); + + mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap); + mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing); + mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size); + mBubbleElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_elevation); + setClipToPadding(false); + + mBubbleBarBackground = new BubbleBarBackground(mActivityContext, + getResources().getDimensionPixelSize(R.dimen.bubblebar_size)); + setBackgroundDrawable(mBubbleBarBackground); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + mBubbleBarBounds.left = left; + mBubbleBarBounds.top = top; + mBubbleBarBounds.right = right; + mBubbleBarBounds.bottom = bottom; + + // The bubble bar handle is aligned to the bottom edge of the screen so scale towards that. + setPivotX(getWidth()); + setPivotY(getHeight()); + + // Position the views + updateChildrenRenderNodeProperties(); + } + + /** + * Returns the bounds of the bubble bar. + */ + public Rect getBubbleBarBounds() { + return mBubbleBarBounds; + } + + // TODO: (b/273592694) animate it + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + if (getChildCount() + 1 > MAX_BUBBLES) { + removeViewInLayout(getChildAt(getChildCount() - 1)); + } + super.addView(child, index, params); + } + + /** + * Updates the z order, positions, and badge visibility of the bubble views in the bar based + * on the expanded state. + */ + // TODO: (b/273592694) animate it + private void updateChildrenRenderNodeProperties() { + int bubbleCount = getChildCount(); + final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f; + for (int i = 0; i < bubbleCount; i++) { + BubbleView bv = (BubbleView) getChildAt(i); + bv.setTranslationY(ty); + if (mIsBarExpanded) { + final float tx = i * (mIconSize + mIconSpacing); + bv.setTranslationX(tx); + bv.setZ(0); + bv.showBadge(); + } else { + bv.setZ((MAX_BUBBLES * mBubbleElevation) - i); + bv.setTranslationX(i * mIconOverlapAmount); + if (i > 0) { + bv.hideBadge(); + } else { + bv.showBadge(); + } + } + } + } + + /** + * Reorders the views to match the provided list. + */ + public void reorder(List viewOrder) { + if (isExpanded()) { + mReorderRunnable = () -> doReorder(viewOrder); + } else { + doReorder(viewOrder); + } + } + + // TODO: (b/273592694) animate it + private void doReorder(List viewOrder) { + if (!isExpanded()) { + for (int i = 0; i < viewOrder.size(); i++) { + View child = viewOrder.get(i); + if (child != null) { + removeViewInLayout(child); + addViewInLayout(child, i, child.getLayoutParams()); + } + } + updateChildrenRenderNodeProperties(); + } + } + + /** + * Sets which bubble view should be shown as selected. + */ + // TODO: (b/273592694) animate it + public void setSelectedBubble(BubbleView view) { + mSelectedBubbleView = view; + updateArrowForSelected(); + invalidate(); + } + + private void updateArrowForSelected() { + if (mSelectedBubbleView == null) { + Log.w(TAG, "trying to update selection arrow without a selected view!"); + return; + } + final int index = indexOfChild(mSelectedBubbleView); + // Find the center of the bubble when it's expanded, set the arrow position to it. + final float tx = getPaddingStart() + index * (mIconSize + mIconSpacing) + mIconSize / 2f; + mBubbleBarBackground.setArrowPosition(tx); + } + + @Override + public void setOnClickListener(View.OnClickListener listener) { + mOnClickListener = listener; + setOrUnsetClickListener(); + } + + /** + * The click listener used for the bubble view gets added / removed depending on whether + * the bar is expanded or collapsed, this updates whether the listener is set based on state. + */ + private void setOrUnsetClickListener() { + super.setOnClickListener(mIsBarExpanded ? null : mOnClickListener); + } + + /** + * Sets whether the bubble bar is expanded or collapsed. + */ + // TODO: (b/273592694) animate it + public void setExpanded(boolean isBarExpanded) { + if (mIsBarExpanded != isBarExpanded) { + mIsBarExpanded = isBarExpanded; + updateArrowForSelected(); + setOrUnsetClickListener(); + if (!isBarExpanded && mReorderRunnable != null) { + mReorderRunnable.run(); + mReorderRunnable = null; + } + mBubbleBarBackground.showArrow(mIsBarExpanded); + requestLayout(); // trigger layout to reposition views & update size for expansion + } + } + + /** + * Returns whether the bubble bar is expanded. + */ + public boolean isExpanded() { + return mIsBarExpanded; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int childCount = getChildCount(); + final float iconWidth = mIsBarExpanded + ? (childCount * (mIconSize + mIconSpacing)) + : mIconSize + ((childCount - 1) * mIconOverlapAmount); + final int totalWidth = (int) iconWidth + getPaddingStart() + getPaddingEnd(); + setMeasuredDimension(totalWidth, MeasureSpec.getSize(heightMeasureSpec)); + + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + measureChild(child, (int) mIconSize, (int) mIconSize); + } + } + + /** + * Returns whether the given MotionEvent, *in screen coordinates*, is within bubble bar + * touch bounds. + */ + public boolean isEventOverAnyItem(MotionEvent ev) { + if (getVisibility() == View.VISIBLE) { + getBoundsOnScreen(mTempRect); + return mTempRect.contains((int) ev.getX(), (int) ev.getY()); + } + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (!mIsBarExpanded) { + // When the bar is collapsed, all taps on it should expand it. + return true; + } + return super.onInterceptTouchEvent(ev); + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java new file mode 100644 index 0000000000..0afc2cb4fe --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.bubbles; + +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; + +import android.graphics.Rect; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.FrameLayout; + +import com.android.launcher3.R; +import com.android.launcher3.anim.AnimatedFloat; +import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarControllers; +import com.android.launcher3.util.MultiPropertyFactory; +import com.android.launcher3.util.MultiValueAlpha; + +import java.util.List; +import java.util.Objects; + +/** + * Controller for {@link BubbleBarView}. Manages the visibility of the bubble bar as well as + * responding to changes in bubble state provided by BubbleBarController. + */ +public class BubbleBarViewController { + + private static final String TAG = BubbleBarViewController.class.getSimpleName(); + + private final TaskbarActivityContext mActivity; + private final BubbleBarView mBarView; + private final int mIconSize; + + // Initialized in init. + private BubbleStashController mBubbleStashController; + private BubbleBarController mBubbleBarController; + private View.OnClickListener mBubbleClickListener; + private View.OnClickListener mBubbleBarClickListener; + + // These are exposed to {@link BubbleStashController} to animate for stashing/un-stashing + private final MultiValueAlpha mBubbleBarAlpha; + private final AnimatedFloat mBubbleBarScale = new AnimatedFloat(this::updateScale); + private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat( + this::updateTranslationY); + + // Modified when swipe up is happening on the bubble bar or task bar. + private float mBubbleBarSwipeUpTranslationY; + + // Whether the bar is hidden for a sysui state. + private boolean mHiddenForSysui; + // Whether the bar is hidden because there are no bubbles. + private boolean mHiddenForNoBubbles; + + public BubbleBarViewController(TaskbarActivityContext activity, BubbleBarView barView) { + mActivity = activity; + mBarView = barView; + mBubbleBarAlpha = new MultiValueAlpha(mBarView, 1 /* num alpha channels */); + mBubbleBarAlpha.setUpdateVisibility(true); + mIconSize = activity.getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size); + } + + public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) { + mBubbleStashController = bubbleControllers.bubbleStashController; + mBubbleBarController = bubbleControllers.bubbleBarController; + + mActivity.addOnDeviceProfileChangeListener(dp -> + mBarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarHeight + ); + mBarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarHeight; + mBubbleBarScale.updateValue(1f); + mBubbleClickListener = v -> onBubbleClicked(v); + mBubbleBarClickListener = v -> setExpanded(true); + mBarView.setOnClickListener(mBubbleBarClickListener); + // TODO: when barView layout changes tell taskbarInsetsController the insets have changed. + } + + private void onBubbleClicked(View v) { + BubbleBarBubble bubble = ((BubbleView) v).getBubble(); + if (bubble == null) { + Log.e(TAG, "bubble click listener, bubble was null"); + } + final String currentlySelected = mBubbleBarController.getSelectedBubbleKey(); + if (mBarView.isExpanded() && Objects.equals(bubble.getKey(), currentlySelected)) { + // Tapping the currently selected bubble while expanded collapses the view. + setExpanded(false); + mBubbleStashController.stashBubbleBar(); + } else { + mBubbleBarController.setSelectedBubble(bubble); + // TODO: Tell SysUi to show the expanded view for this bubble. + } + } + + // + // The below animators are exposed to BubbleStashController so it can manage the stashing + // animation. + // + + public MultiPropertyFactory getBubbleBarAlpha() { + return mBubbleBarAlpha; + } + + public AnimatedFloat getBubbleBarScale() { + return mBubbleBarScale; + } + + public AnimatedFloat getBubbleBarTranslationY() { + return mBubbleBarTranslationY; + } + + /** + * Whether the bubble bar is visible or not. + */ + public boolean isBubbleBarVisible() { + return mBarView.getVisibility() == VISIBLE; + } + + /** + * The bounds of the bubble bar. + */ + public Rect getBubbleBarBounds() { + return mBarView.getBubbleBarBounds(); + } + + /** + * When the bubble bar is not stashed, it can be collapsed (the icons are in a stack) or + * expanded (the icons are in a row). This indicates whether the bubble bar is expanded. + */ + public boolean isExpanded() { + return mBarView.isExpanded(); + } + + /** + * Whether the motion event is within the bounds of the bubble bar. + */ + public boolean isEventOverAnyItem(MotionEvent ev) { + return mBarView.isEventOverAnyItem(ev); + } + + // + // Visibility of the bubble bar + // + + /** + * Returns whether the bubble bar is hidden because there are no bubbles. + */ + public boolean isHiddenForNoBubbles() { + return mHiddenForNoBubbles; + } + + /** + * Sets whether the bubble bar should be hidden because there are no bubbles. + */ + public void setHiddenForBubbles(boolean hidden) { + if (mHiddenForNoBubbles != hidden) { + mHiddenForNoBubbles = hidden; + updateVisibilityForStateChange(); + } + } + + /** + * Sets whether the bubble bar should be hidden due to SysUI state (e.g. on lockscreen). + */ + public void setHiddenForSysui(boolean hidden) { + if (mHiddenForSysui != hidden) { + mHiddenForSysui = hidden; + updateVisibilityForStateChange(); + } + } + + // TODO: (b/273592694) animate it + private void updateVisibilityForStateChange() { + if (!mHiddenForSysui && !mBubbleStashController.isStashed() && !mHiddenForNoBubbles) { + mBarView.setVisibility(VISIBLE); + } else { + mBarView.setVisibility(INVISIBLE); + } + } + + // + // Modifying view related properties. + // + + /** + * Sets the translation of the bubble bar during the swipe up gesture. + */ + public void setTranslationYForSwipe(float transY) { + mBubbleBarSwipeUpTranslationY = transY; + updateTranslationY(); + } + + private void updateTranslationY() { + mBarView.setTranslationY(mBubbleBarTranslationY.value + + mBubbleBarSwipeUpTranslationY); + } + + /** + * Applies scale properties for the entire bubble bar. + */ + private void updateScale() { + float scale = mBubbleBarScale.value; + mBarView.setScaleX(scale); + mBarView.setScaleY(scale); + } + + // + // Manipulating the specific bubble views in the bar + // + + /** + * Removes the provided bubble from the bubble bar. + */ + public void removeBubble(BubbleBarBubble b) { + if (b != null) { + mBarView.removeView(b.getView()); + } else { + Log.w(TAG, "removeBubble, bubble was null!"); + } + } + + /** + * Adds the provided bubble to the bubble bar. + */ + public void addBubble(BubbleBarBubble b) { + if (b != null) { + mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize)); + b.getView().setOnClickListener(mBubbleClickListener); + } else { + Log.w(TAG, "addBubble, bubble was null!"); + } + } + + /** + * Reorders the bubbles based on the provided list. + */ + public void reorderBubbles(List newOrder) { + List viewList = newOrder.stream().filter(Objects::nonNull) + .map(BubbleBarBubble::getView).toList(); + mBarView.reorder(viewList); + } + + /** + * Updates the selected bubble. + */ + public void updateSelectedBubble(BubbleBarBubble newlySelected) { + mBarView.setSelectedBubble(newlySelected.getView()); + } + + /** + * Sets whether the bubble bar should be expanded (not unstashed, but have the contents + * within it expanded). This method notifies SystemUI that the bubble bar is expanded and + * showing a selected bubble. This method should ONLY be called from UI events originating + * from Launcher. + */ + public void setExpanded(boolean isExpanded) { + if (isExpanded != mBarView.isExpanded()) { + mBarView.setExpanded(isExpanded); + if (!isExpanded) { + // TODO: Tell SysUi to collapse the bubble + } else { + final String selectedKey = mBubbleBarController.getSelectedBubbleKey(); + if (selectedKey != null) { + // TODO: Tell SysUi to show the bubble + } else { + Log.w(TAG, "trying to expand bubbles when there isn't one selected"); + } + // TODO: Tell taskbar stash controller to stash without bubbles following + } + } + } + + /** + * Sets whether the bubble bar should be expanded. This method is used in response to UI events + * from SystemUI. + */ + public void setExpandedFromSysui(boolean isExpanded) { + if (!isExpanded) { + mBubbleStashController.stashBubbleBar(); + } else { + mBubbleStashController.showBubbleBar(true /* expand the bubbles */); + } + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java new file mode 100644 index 0000000000..6417f3c585 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.bubbles; + +import com.android.launcher3.taskbar.TaskbarControllers; +import com.android.launcher3.util.RunnableList; + +/** + * Hosts various bubble controllers to facilitate passing between one another. + */ +public class BubbleControllers { + + public final BubbleBarController bubbleBarController; + public final BubbleBarViewController bubbleBarViewController; + public final BubbleStashController bubbleStashController; + public final BubbleStashedHandleViewController bubbleStashedHandleViewController; + + private final RunnableList mPostInitRunnables = new RunnableList(); + + /** + * Want to add a new controller? Don't forget to: + * * Call init + * * Call onDestroy + */ + public BubbleControllers( + BubbleBarController bubbleBarController, + BubbleBarViewController bubbleBarViewController, + BubbleStashController bubbleStashController, + BubbleStashedHandleViewController bubbleStashedHandleViewController) { + this.bubbleBarController = bubbleBarController; + this.bubbleBarViewController = bubbleBarViewController; + this.bubbleStashController = bubbleStashController; + this.bubbleStashedHandleViewController = bubbleStashedHandleViewController; + } + + /** + * Initializes all controllers. Note that controllers can now reference each other through this + * BubbleControllers instance, but should be careful to only access things that were created + * in constructors for now, as some controllers may still be waiting for init(). + */ + public void init(TaskbarControllers taskbarControllers) { + bubbleBarController.init(taskbarControllers, this); + bubbleBarViewController.init(taskbarControllers, this); + bubbleStashedHandleViewController.init(taskbarControllers, this); + bubbleStashController.init(taskbarControllers, this); + + mPostInitRunnables.executeAllAndDestroy(); + } + + /** + * If all controllers are already initialized, runs the given callback immediately. Otherwise, + * queues it to run after calling init() on all controllers. This should likely be used in any + * case where one controller is telling another controller to do something inside init(). + */ + public void runAfterInit(Runnable runnable) { + // If this has been executed in init, it automatically runs adds to it. + mPostInitRunnables.add(runnable); + } + + /** + * Cleans up all controllers. + */ + public void onDestroy() { + bubbleStashedHandleViewController.onDestroy(); + bubbleBarController.onDestroy(); + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java new file mode 100644 index 0000000000..0ab53b0c20 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.bubbles; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.annotation.Nullable; +import android.view.InsetsController; + +import com.android.launcher3.anim.AnimatedFloat; +import com.android.launcher3.taskbar.StashedHandleViewController; +import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarControllers; +import com.android.launcher3.taskbar.TaskbarStashController; +import com.android.launcher3.util.MultiPropertyFactory; + +/** + * Coordinates between controllers such as BubbleBarView and BubbleHandleViewController to + * create a cohesive animation between stashed/unstashed states. + */ +public class BubbleStashController { + + private static final String TAG = BubbleStashController.class.getSimpleName(); + + /** + * How long to stash/unstash. + */ + public static final long BAR_STASH_DURATION = InsetsController.ANIMATION_DURATION_RESIZE; + + /** + * The scale bubble bar animates to when being stashed. + */ + private static final float STASHED_BAR_SCALE = 0.5f; + + protected final TaskbarActivityContext mActivity; + + // Initialized in init. + private TaskbarControllers mControllers; + private BubbleBarViewController mBarViewController; + private BubbleStashedHandleViewController mHandleViewController; + private TaskbarStashController mTaskbarStashController; + + private MultiPropertyFactory.MultiProperty mIconAlphaForStash; + private AnimatedFloat mIconScaleForStash; + private AnimatedFloat mIconTranslationYForStash; + private MultiPropertyFactory.MultiProperty mBubbleStashedHandleAlpha; + + private boolean mRequestedStashState; + private boolean mRequestedExpandedState; + + private boolean mIsStashed; + private int mStashedHeight; + private int mUnstashedHeight; + private boolean mBubblesShowingOnHome; + private boolean mBubblesShowingOnOverview; + + @Nullable + private AnimatorSet mAnimator; + + public BubbleStashController(TaskbarActivityContext activity) { + mActivity = activity; + } + + public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) { + mControllers = controllers; + mBarViewController = bubbleControllers.bubbleBarViewController; + mHandleViewController = bubbleControllers.bubbleStashedHandleViewController; + mTaskbarStashController = controllers.taskbarStashController; + + mIconAlphaForStash = mBarViewController.getBubbleBarAlpha().get(0); + mIconScaleForStash = mBarViewController.getBubbleBarScale(); + mIconTranslationYForStash = mBarViewController.getBubbleBarTranslationY(); + + mBubbleStashedHandleAlpha = mHandleViewController.getStashedHandleAlpha().get( + StashedHandleViewController.ALPHA_INDEX_STASHED); + + mStashedHeight = mHandleViewController.getStashedHeight(); + mUnstashedHeight = mHandleViewController.getUnstashedHeight(); + + bubbleControllers.runAfterInit(() -> { + if (mTaskbarStashController.isStashed()) { + stashBubbleBar(); + } else { + showBubbleBar(false /* expandBubbles */); + } + }); + } + + /** + * Returns the touchable height of the bubble bar based on it's stashed state. + */ + public int getTouchableHeight() { + return mIsStashed ? mStashedHeight : mUnstashedHeight; + } + + /** + * Returns whether the bubble bar is currently stashed. + */ + public boolean isStashed() { + return mIsStashed; + } + + /** + * Called when launcher enters or exits the home page. Bubbles are unstashed on home. + */ + public void setBubblesShowingOnHome(boolean onHome) { + if (mBubblesShowingOnHome != onHome) { + mBubblesShowingOnHome = onHome; + if (mBubblesShowingOnHome) { + showBubbleBar(/* expanded= */ false); + } else if (!mBarViewController.isExpanded()) { + stashBubbleBar(); + } + } + } + + /** Whether bubbles are showing on the launcher home page. */ + public boolean isBubblesShowingOnHome() { + return mBubblesShowingOnHome; + } + + // TODO: when tapping on an app in overview, this is a bit delayed compared to taskbar stashing + /** Called when launcher enters or exits overview. Bubbles are unstashed on overview. */ + public void setBubblesShowingOnOverview(boolean onOverview) { + if (mBubblesShowingOnOverview != onOverview) { + mBubblesShowingOnOverview = onOverview; + if (!mBubblesShowingOnOverview && !mBarViewController.isExpanded()) { + stashBubbleBar(); + } + } + } + + /** Called when sysui locked state changes, when locked, bubble bar is stashed. */ + public void onSysuiLockedStateChange(boolean isSysuiLocked) { + if (isSysuiLocked) { + // TODO: should the normal path flip mBubblesOnHome / check if this is needed + // If we're locked, we're no longer showing on home. + mBubblesShowingOnHome = false; + mBubblesShowingOnOverview = false; + stashBubbleBar(); + } + } + + /** + * Stashes the bubble bar if allowed based on other state (e.g. on home and overview the + * bar does not stash). + */ + public void stashBubbleBar() { + mRequestedStashState = true; + mRequestedExpandedState = false; + updateStashedAndExpandedState(); + } + + /** + * Shows the bubble bar, and expands bubbles depending on {@param expandBubbles}. + */ + public void showBubbleBar(boolean expandBubbles) { + mRequestedStashState = false; + mRequestedExpandedState = expandBubbles; + updateStashedAndExpandedState(); + } + + private void updateStashedAndExpandedState() { + if (mBarViewController.isHiddenForNoBubbles()) { + // If there are no bubbles the bar and handle are invisible, nothing to do here. + return; + } + boolean isStashed = mRequestedStashState + && !mBubblesShowingOnHome + && !mBubblesShowingOnOverview; + if (mIsStashed != isStashed) { + mIsStashed = isStashed; + if (mAnimator != null) { + mAnimator.cancel(); + } + mAnimator = createStashAnimator(mIsStashed, BAR_STASH_DURATION); + mAnimator.start(); + onIsStashedChanged(); + } + if (mBarViewController.isExpanded() != mRequestedExpandedState) { + mBarViewController.setExpanded(mRequestedExpandedState); + } + } + + /** + * Create a stash animation. + * + * @param isStashed whether it's a stash animation or an unstash animation + * @param duration duration of the animation + * @return the animation + */ + private AnimatorSet createStashAnimator(boolean isStashed, long duration) { + AnimatorSet animatorSet = new AnimatorSet(); + final float stashTranslation = (mUnstashedHeight - mStashedHeight) / 2f; + + AnimatorSet fullLengthAnimatorSet = new AnimatorSet(); + // Not exactly half and may overlap. See [first|second]HalfDurationScale below. + AnimatorSet firstHalfAnimatorSet = new AnimatorSet(); + AnimatorSet secondHalfAnimatorSet = new AnimatorSet(); + + final float firstHalfDurationScale; + final float secondHalfDurationScale; + + if (isStashed) { + firstHalfDurationScale = 0.75f; + secondHalfDurationScale = 0.5f; + + fullLengthAnimatorSet.play(mIconTranslationYForStash.animateToValue(stashTranslation)); + + firstHalfAnimatorSet.playTogether( + mIconAlphaForStash.animateToValue(0), + mIconScaleForStash.animateToValue(STASHED_BAR_SCALE)); + secondHalfAnimatorSet.playTogether( + mBubbleStashedHandleAlpha.animateToValue(1)); + } else { + firstHalfDurationScale = 0.5f; + secondHalfDurationScale = 0.75f; + + // If we're on home, adjust the translation so the bubble bar aligns with hotseat. + final float hotseatTransY = mActivity.getDeviceProfile().getTaskbarOffsetY(); + final float translationY = mBubblesShowingOnHome ? hotseatTransY : 0; + fullLengthAnimatorSet.playTogether( + mIconScaleForStash.animateToValue(1), + mIconTranslationYForStash.animateToValue(translationY)); + + firstHalfAnimatorSet.playTogether( + mBubbleStashedHandleAlpha.animateToValue(0) + ); + secondHalfAnimatorSet.playTogether( + mIconAlphaForStash.animateToValue(1) + ); + } + + fullLengthAnimatorSet.play(mHandleViewController.createRevealAnimToIsStashed(isStashed)); + + fullLengthAnimatorSet.setDuration(duration); + firstHalfAnimatorSet.setDuration((long) (duration * firstHalfDurationScale)); + secondHalfAnimatorSet.setDuration((long) (duration * secondHalfDurationScale)); + secondHalfAnimatorSet.setStartDelay((long) (duration * (1 - secondHalfDurationScale))); + + animatorSet.playTogether(fullLengthAnimatorSet, firstHalfAnimatorSet, + secondHalfAnimatorSet); + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAnimator = null; + mControllers.runAfterInit(() -> { + if (isStashed) { + mBarViewController.setExpanded(false); + } + }); + } + }); + return animatorSet; + } + + private void onIsStashedChanged() { + mControllers.runAfterInit(() -> { + mHandleViewController.onIsStashedChanged(); + // TODO: when stash changes tell taskbarInsetsController the insets have changed. + }); + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java new file mode 100644 index 0000000000..2170a5dc5b --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.bubbles; + +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.content.res.Resources; +import android.graphics.Outline; +import android.graphics.Rect; +import android.view.View; +import android.view.ViewOutlineProvider; + +import com.android.launcher3.R; +import com.android.launcher3.anim.RevealOutlineAnimation; +import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; +import com.android.launcher3.taskbar.StashedHandleView; +import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarControllers; +import com.android.launcher3.util.Executors; +import com.android.launcher3.util.MultiPropertyFactory; +import com.android.launcher3.util.MultiValueAlpha; +import com.android.systemui.shared.navigationbar.RegionSamplingHelper; + +/** + * Handles properties/data collection, then passes the results to our stashed handle View to render. + */ +public class BubbleStashedHandleViewController { + + private final TaskbarActivityContext mActivity; + private final StashedHandleView mStashedHandleView; + private final MultiValueAlpha mTaskbarStashedHandleAlpha; + + // Initialized in init. + private BubbleBarViewController mBarViewController; + private BubbleStashController mBubbleStashController; + private RegionSamplingHelper mRegionSamplingHelper; + private int mBarSize; + private int mStashedHandleWidth; + private int mStashedHandleHeight; + + // The bounds we want to clip to in the settled state when showing the stashed handle. + private final Rect mStashedHandleBounds = new Rect(); + + // When the reveal animation is cancelled, we can assume it's about to create a new animation, + // which should start off at the same point the cancelled one left off. + private float mStartProgressForNextRevealAnim; + private boolean mWasLastRevealAnimReversed; + + // XXX: if there are more of these maybe do state flags instead + private boolean mHiddenForSysui; + private boolean mHiddenForNoBubbles; + private boolean mHiddenForHomeButtonDisabled; + + public BubbleStashedHandleViewController(TaskbarActivityContext activity, + StashedHandleView stashedHandleView) { + mActivity = activity; + mStashedHandleView = stashedHandleView; + mTaskbarStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, 1); + } + + public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) { + mBarViewController = bubbleControllers.bubbleBarViewController; + mBubbleStashController = bubbleControllers.bubbleStashController; + + Resources resources = mActivity.getResources(); + mStashedHandleHeight = resources.getDimensionPixelSize( + R.dimen.bubblebar_stashed_handle_height); + mStashedHandleWidth = resources.getDimensionPixelSize( + R.dimen.bubblebar_stashed_handle_width); + mBarSize = resources.getDimensionPixelSize(R.dimen.bubblebar_size); + + final int bottomMargin = resources.getDimensionPixelSize( + R.dimen.transient_taskbar_bottom_margin); + mStashedHandleView.getLayoutParams().height = mBarSize + bottomMargin; + + mTaskbarStashedHandleAlpha.get(0).setValue(0); + + final int stashedTaskbarHeight = resources.getDimensionPixelSize( + R.dimen.bubblebar_stashed_size); + mStashedHandleView.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + float stashedHandleRadius = view.getHeight() / 2f; + outline.setRoundRect(mStashedHandleBounds, stashedHandleRadius); + } + }); + + mRegionSamplingHelper = new RegionSamplingHelper(mStashedHandleView, + new RegionSamplingHelper.SamplingCallback() { + @Override + public void onRegionDarknessChanged(boolean isRegionDark) { + mStashedHandleView.updateHandleColor(isRegionDark, true /* animate */); + } + + @Override + public Rect getSampledRegion(View sampledView) { + return mStashedHandleView.getSampledRegion(); + } + }, Executors.UI_HELPER_EXECUTOR); + + mStashedHandleView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) -> { + // As more bubbles get added, the icon bounds become larger. To ensure a consistent + // handle bar position, we pin it to the edge of the screen. + Rect bubblebarRect = mBarViewController.getBubbleBarBounds(); + final int stashedCenterY = view.getHeight() - stashedTaskbarHeight / 2; + + mStashedHandleBounds.set( + bubblebarRect.right - mStashedHandleWidth, + stashedCenterY - mStashedHandleHeight / 2, + bubblebarRect.right, + stashedCenterY + mStashedHandleHeight / 2); + mStashedHandleView.updateSampledRegion(mStashedHandleBounds); + + view.setPivotX(view.getWidth()); + view.setPivotY(view.getHeight() - stashedTaskbarHeight / 2f); + }); + } + + public void onDestroy() { + mRegionSamplingHelper.stopAndDestroy(); + mRegionSamplingHelper = null; + } + + /** + * Returns the height of the stashed handle. + */ + public int getStashedHeight() { + return mStashedHandleHeight; + } + + /** + * Returns the height when the bubble bar is unstashed (so the height of the bubble bar). + */ + public int getUnstashedHeight() { + return mBarSize; + } + + /** + * Called when system ui state changes. Bubbles don't show when the device is locked. + */ + public void setHiddenForSysui(boolean hidden) { + if (mHiddenForSysui != hidden) { + mHiddenForSysui = hidden; + updateVisibilityForStateChange(); + } + } + + /** + * Called when the handle should be hidden (or shown) because there are no bubbles + * (or 1+ bubbles). + */ + public void setHiddenForBubbles(boolean hidden) { + if (mHiddenForNoBubbles != hidden) { + mHiddenForNoBubbles = hidden; + updateVisibilityForStateChange(); + } + } + + /** + * Called when the home button is enabled / disabled. Bubbles don't show if home is disabled. + */ + // TODO: is this needed for bubbles? + public void setIsHomeButtonDisabled(boolean homeDisabled) { + mHiddenForHomeButtonDisabled = homeDisabled; + updateVisibilityForStateChange(); + } + + // TODO: (b/273592694) animate it? + private void updateVisibilityForStateChange() { + if (!mHiddenForSysui && !mHiddenForHomeButtonDisabled && !mHiddenForNoBubbles) { + mStashedHandleView.setVisibility(VISIBLE); + } else { + mStashedHandleView.setVisibility(INVISIBLE); + } + updateRegionSampling(); + } + + /** + * Called when bubble bar is stash state changes so that updates to the stashed handle color + * can be started or stopped. + */ + public void onIsStashedChanged() { + updateRegionSampling(); + } + + private void updateRegionSampling() { + boolean handleVisible = mStashedHandleView.getVisibility() == VISIBLE + && mBubbleStashController.isStashed(); + mRegionSamplingHelper.setWindowVisible(handleVisible); + if (handleVisible) { + mStashedHandleView.updateSampledRegion(mStashedHandleBounds); + mRegionSamplingHelper.start(mStashedHandleView.getSampledRegion()); + } else { + mRegionSamplingHelper.stop(); + } + } + + /** + * Sets the translation of the stashed handle during the swipe up gesture. + */ + public void setTranslationYForSwipe(float transY) { + mStashedHandleView.setTranslationY(transY); + } + + /** + * Used by {@link BubbleStashController} to animate the handle when stashing or un stashing. + */ + public MultiPropertyFactory getStashedHandleAlpha() { + return mTaskbarStashedHandleAlpha; + } + + /** + * Creates and returns an Animator that updates the stashed handle shape and size. + * When stashed, the shape is a thin rounded pill. When unstashed, the shape morphs into + * the size of where the bubble bar icons will be. + */ + public Animator createRevealAnimToIsStashed(boolean isStashed) { + Rect bubbleBarBounds = new Rect(mBarViewController.getBubbleBarBounds()); + + // Account for the full visual height of the bubble bar + int heightDiff = (mBarSize - bubbleBarBounds.height()) / 2; + bubbleBarBounds.top -= heightDiff; + bubbleBarBounds.bottom += heightDiff; + float stashedHandleRadius = mStashedHandleView.getHeight() / 2f; + final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider( + stashedHandleRadius, stashedHandleRadius, bubbleBarBounds, mStashedHandleBounds); + + boolean isReversed = !isStashed; + boolean changingDirection = mWasLastRevealAnimReversed != isReversed; + mWasLastRevealAnimReversed = isReversed; + if (changingDirection) { + mStartProgressForNextRevealAnim = 1f - mStartProgressForNextRevealAnim; + } + + ValueAnimator revealAnim = handleRevealProvider.createRevealAnimator(mStashedHandleView, + isReversed, mStartProgressForNextRevealAnim); + revealAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mStartProgressForNextRevealAnim = ((ValueAnimator) animation).getAnimatedFraction(); + } + }); + return revealAnim; + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java new file mode 100644 index 0000000000..e22e63aa36 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.bubbles; + +import android.annotation.Nullable; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Outline; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; + +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.android.launcher3.R; +import com.android.launcher3.icons.IconNormalizer; + +// TODO: (b/276978250) This is will be similar to WMShell's BadgedImageView, it'd be nice to share. +// TODO: (b/269670235) currently this doesn't show the 'update dot' +/** + * View that displays a bubble icon, along with an app badge on either the left or + * right side of the view. + */ +public class BubbleView extends ConstraintLayout { + + // TODO: (b/269670235) currently we don't render the 'update dot', this will be used for that. + public static final int DEFAULT_PATH_SIZE = 100; + + private final ImageView mBubbleIcon; + private final ImageView mAppIcon; + private final int mBubbleSize; + + // TODO: (b/273310265) handle RTL + private boolean mOnLeft = false; + + private BubbleBarBubble mBubble; + + public BubbleView(Context context) { + this(context, null); + } + + public BubbleView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BubbleView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public BubbleView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + // We manage positioning the badge ourselves + setLayoutDirection(LAYOUT_DIRECTION_LTR); + + LayoutInflater.from(context).inflate(R.layout.bubble_view, this); + + mBubbleSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size); + mBubbleIcon = findViewById(R.id.icon_view); + mAppIcon = findViewById(R.id.app_icon_view); + + setFocusable(true); + setClickable(true); + setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + BubbleView.this.getOutline(outline); + } + }); + } + + private void getOutline(Outline outline) { + final int normalizedSize = IconNormalizer.getNormalizedCircleSize(mBubbleSize); + final int inset = (mBubbleSize - normalizedSize) / 2; + outline.setOval(inset, inset, inset + normalizedSize, inset + normalizedSize); + } + + /** Sets the bubble being rendered in this view. */ + void setBubble(BubbleBarBubble bubble) { + mBubble = bubble; + mBubbleIcon.setImageBitmap(bubble.getIcon()); + mAppIcon.setImageBitmap(bubble.getBadge()); + } + + /** Returns the bubble being rendered in this view. */ + @Nullable + BubbleBarBubble getBubble() { + return mBubble; + } + + /** Shows the app badge on this bubble. */ + void showBadge() { + Bitmap appBadgeBitmap = mBubble.getBadge(); + if (appBadgeBitmap == null) { + mAppIcon.setVisibility(GONE); + return; + } + + int translationX; + if (mOnLeft) { + translationX = -(mBubble.getIcon().getWidth() - appBadgeBitmap.getWidth()); + } else { + translationX = 0; + } + + mAppIcon.setTranslationX(translationX); + mAppIcon.setVisibility(VISIBLE); + } + + /** Hides the app badge on this bubble. */ + void hideBadge() { + mAppIcon.setVisibility(GONE); + } + + @Override + public String toString() { + return "BubbleView{" + mBubble + "}"; + } +} diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java index 3990dade70..0eef70e270 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java @@ -402,8 +402,9 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView { PredictedAppIcon icon = (PredictedAppIcon) LayoutInflater.from(parent.getContext()) .inflate(R.layout.predicted_app_icon, parent, false); icon.applyFromWorkspaceItem(info); - icon.setOnClickListener(ItemClickHandler.INSTANCE); - icon.setOnFocusChangeListener(Launcher.getLauncher(parent.getContext()).getFocusHandler()); + Launcher launcher = Launcher.getLauncher(parent.getContext()); + icon.setOnClickListener(launcher.getItemOnClickListener()); + icon.setOnFocusChangeListener(launcher.getFocusHandler()); return icon; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index 08d147f7cf..163c36fa24 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -56,6 +56,10 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler { return RemoteViews.startPendingIntent(hostView, pendingIntent, remoteResponse.getLaunchOptions(view)); } + if (mLauncher.getSplitToWorkspaceController().handleSecondWidgetSelectionForSplit(view, + pendingIntent)) { + return true; + } Pair options = remoteResponse.getLaunchOptions(view); ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager() .getActivityLaunchOptions(hostView); diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index b2b062344e..d67dbaec09 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -74,6 +74,7 @@ import android.hardware.SensorManager; import android.hardware.devicestate.DeviceStateManager; import android.hardware.display.DisplayManager; import android.media.permission.SafeCloseable; +import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.IBinder; @@ -91,6 +92,7 @@ import android.window.SplashScreen; import androidx.annotation.BinderThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import com.android.app.viewcapture.SettingsAwareViewCapture; import com.android.launcher3.AbstractFloatingView; @@ -764,6 +766,7 @@ public class QuickstepLauncher extends Launcher { mActiveOnBackAnimationCallback.onBackStarted(backEvent); } + @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @Override public void onBackInvoked() { // Recreate mActiveOnBackAnimationCallback if necessary to avoid NPE @@ -970,8 +973,8 @@ public class QuickstepLauncher extends Launcher { return mTaskbarUIController; } - public SplitSelectStateController getSplitSelectStateController() { - return mSplitSelectStateController; + public SplitToWorkspaceController getSplitToWorkspaceController() { + return mSplitToWorkspaceController; } public T getActionsView() { @@ -1178,6 +1181,11 @@ public class QuickstepLauncher extends Launcher { } } + @Override + public void tryClearAccessibilityFocus(View view) { + view.clearAccessibilityFocus(); + } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java index 9c59361431..87c836bbac 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java +++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java @@ -16,12 +16,10 @@ package com.android.launcher3.uioverrides.flags; -import static com.android.launcher3.config.FeatureFlags.FLAGS_PREF_NAME; import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD; import static com.android.launcher3.uioverrides.flags.FlagsFactory.TEAMFOOD_FLAG; import android.content.Context; -import android.content.SharedPreferences; import android.os.Handler; import android.os.Process; import android.text.Html; @@ -52,31 +50,27 @@ public final class FlagTogglerPrefUi { private final PreferenceFragmentCompat mFragment; private final Context mContext; - private final SharedPreferences mSharedPreferences; - private final PreferenceDataStore mDataStore = new PreferenceDataStore() { @Override public void putBoolean(String key, boolean value) { - mSharedPreferences.edit().putBoolean(key, value).apply(); + FlagsFactory.getSharedPreferences().edit().putBoolean(key, value).apply(); updateMenu(); } @Override public boolean getBoolean(String key, boolean defaultValue) { - return mSharedPreferences.getBoolean(key, defaultValue); + return FlagsFactory.getSharedPreferences().getBoolean(key, defaultValue); } }; public FlagTogglerPrefUi(PreferenceFragmentCompat fragment) { mFragment = fragment; mContext = fragment.getActivity(); - mSharedPreferences = mContext.getSharedPreferences( - FLAGS_PREF_NAME, Context.MODE_PRIVATE); } public void applyTo(PreferenceGroup parent) { - Set modifiedPrefs = mSharedPreferences.getAll().keySet(); + Set modifiedPrefs = FlagsFactory.getSharedPreferences().getAll().keySet(); List flags = FlagsFactory.getDebugFlags(); flags.sort((f1, f2) -> { // Sort first by any prefs that the user has changed, then alphabetically. @@ -102,7 +96,7 @@ public final class FlagTogglerPrefUi { public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); holder.itemView.setOnLongClickListener(v -> { - mSharedPreferences.edit().remove(flag.key).apply(); + FlagsFactory.getSharedPreferences().edit().remove(flag.key).apply(); setChecked(getFlagStateFromSharedPrefs(flag)); updateSummary(this, flag); updateMenu(); @@ -133,7 +127,7 @@ public final class FlagTogglerPrefUi { private void updateSummary(SwitchPreference switchPreference, DebugFlag flag) { String summary = flag.defaultValue == TEAMFOOD ? "[TEAMFOOD] " : ""; - if (mSharedPreferences.contains(flag.key)) { + if (FlagsFactory.getSharedPreferences().contains(flag.key)) { summary += "[OVERRIDDEN] "; } if (!TextUtils.isEmpty(summary)) { @@ -156,7 +150,7 @@ public final class FlagTogglerPrefUi { public void onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_apply_flags) { - mSharedPreferences.edit().commit(); + FlagsFactory.getSharedPreferences().edit().commit(); Log.e(TAG, "Killing launcher process " + Process.myPid() + " to apply new flag values"); System.exit(0); diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java index d066abe335..a68e753589 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java @@ -21,7 +21,6 @@ import static android.app.ActivityThread.currentApplication; import static com.android.launcher3.BuildConfig.IS_DEBUG_DEVICE; import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED; import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED; -import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.content.Context; @@ -30,6 +29,8 @@ import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.util.Log; +import androidx.annotation.NonNull; + import com.android.launcher3.config.FeatureFlags.BooleanFlag; import com.android.launcher3.config.FeatureFlags.FlagState; import com.android.launcher3.config.FeatureFlags.IntFlag; @@ -52,10 +53,11 @@ public class FlagsFactory { private static final FlagsFactory INSTANCE = new FlagsFactory(); private static final boolean FLAG_AUTO_APPLY_ENABLED = true; - public static final String FLAGS_PREF_NAME = "featureFlags"; + private static final String FLAGS_PREF_NAME = "featureFlags"; public static final String NAMESPACE_LAUNCHER = "launcher"; private static final List sDebugFlags = new ArrayList<>(); + private static SharedPreferences sSharedPreferences; static final BooleanFlag TEAMFOOD_FLAG = getReleaseFlag( 0, "LAUNCHER_TEAMFOOD", DISABLED, "Enable this flag to opt-in all team food flags"); @@ -93,10 +95,8 @@ public class FlagsFactory { public static BooleanFlag getDebugFlag( int bugId, String key, FlagState flagState, String description) { if (IS_DEBUG_DEVICE) { - SharedPreferences prefs = currentApplication() - .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE); boolean defaultValue = getEnabledValue(flagState); - boolean currentValue = prefs.getBoolean(key, defaultValue); + boolean currentValue = getSharedPreferences().getBoolean(key, defaultValue); DebugFlag flag = new DebugFlag(key, description, flagState, currentValue); sDebugFlags.add(flag); return flag; @@ -115,9 +115,7 @@ public class FlagsFactory { boolean defaultValueInCode = getEnabledValue(flagState); boolean defaultValue = DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, defaultValueInCode); if (IS_DEBUG_DEVICE) { - SharedPreferences prefs = currentApplication() - .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE); - boolean currentValue = prefs.getBoolean(key, defaultValue); + boolean currentValue = getSharedPreferences().getBoolean(key, defaultValue); DebugFlag flag = new DeviceFlag(key, description, flagState, currentValue, defaultValueInCode); sDebugFlags.add(flag); @@ -145,6 +143,17 @@ public class FlagsFactory { } } + /** Returns the SharedPreferences instance backing Debug FeatureFlags. */ + @NonNull + static SharedPreferences getSharedPreferences() { + if (sSharedPreferences == null) { + sSharedPreferences = currentApplication() + .createDeviceProtectedStorageContext() + .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE); + } + return sSharedPreferences; + } + /** * Dumps the current flags state to the print writer */ diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index f1c4f68e28..80f5558315 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -15,11 +15,15 @@ */ package com.android.launcher3.uioverrides.touchcontrollers; +import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_MOVE; + import static com.android.launcher3.LauncherAnimUtils.newCancelListener; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME; +import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe; import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe; import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD; import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; @@ -106,6 +110,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, newCancelListener(this::clearState); private boolean mNoIntercept; + private Boolean mIsTrackpadFourFingerSwipe; private LauncherState mStartState; private boolean mIsHomeScreenVisible = true; @@ -131,7 +136,9 @@ public class NoButtonQuickSwitchTouchController implements TouchController, @Override public boolean onControllerInterceptTouchEvent(MotionEvent ev) { - if (ev.getAction() == MotionEvent.ACTION_DOWN) { + int action = ev.getActionMasked(); + if (action == ACTION_DOWN) { + mIsTrackpadFourFingerSwipe = null; mNoIntercept = !canInterceptTouch(ev); if (mNoIntercept) { return false; @@ -140,6 +147,13 @@ public class NoButtonQuickSwitchTouchController implements TouchController, // Only detect horizontal swipe for intercept, then we will allow swipe up as well. mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT, false /* ignoreSlopWhenSettling */); + } else if (isTrackpadMultiFingerSwipe(ev) && mIsTrackpadFourFingerSwipe == null + && action == ACTION_MOVE) { + mIsTrackpadFourFingerSwipe = isTrackpadFourFingerSwipe(ev); + mNoIntercept = !mIsTrackpadFourFingerSwipe; + if (mNoIntercept) { + return false; + } } if (mNoIntercept) { @@ -162,9 +176,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController, if ((ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) == 0) { return false; } - if (isTrackpadMultiFingerSwipe(ev)) { - return false; - } int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags(); if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) { return false; diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index 683f4ea896..395833ffea 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -21,7 +21,6 @@ import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY; -import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN; import android.graphics.PointF; @@ -106,8 +105,7 @@ public class StatusBarTouchController implements TouchController { // Currently input dispatcher will not do touch transfer if there are more than // one touch pointer. Hence, even if slope passed, only set the slippery flag // when there is single touch event. (context: InputDispatcher.cpp line 1445) - if (dy > mTouchSlop && dy > Math.abs(dx) && (isTrackpadMotionEvent(ev) - || ev.getPointerCount() == 1)) { + if (dy > mTouchSlop && dy > Math.abs(dx) && ev.getPointerCount() == 1) { ev.setAction(ACTION_DOWN); dispatchTouchEvent(ev); setWindowSlippery(true); @@ -161,8 +159,7 @@ public class StatusBarTouchController implements TouchController { } else { // For NORMAL state, only listen if the event originated above the navbar height DeviceProfile dp = mLauncher.getDeviceProfile(); - if (!isTrackpadMotionEvent(ev) && ev.getY() > (mLauncher.getDragLayer().getHeight() - - dp.getInsets().bottom)) { + if (ev.getY() > (mLauncher.getDragLayer().getHeight() - dp.getInsets().bottom)) { return false; } } diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 97956701ab..d64347f977 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -105,6 +105,7 @@ import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarUIController; import com.android.launcher3.tracing.InputConsumerProto; import com.android.launcher3.tracing.SwipeHandlerProto; +import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.TraceHelper; @@ -624,7 +625,7 @@ public abstract class AbsSwipeUpHandler, mActivityInterface); }); - notifyGestureStartedAsync(); + notifyGestureStarted(); } private void onDeferredActivityLaunch() { @@ -961,7 +962,7 @@ public abstract class AbsSwipeUpHandler, } }); } - notifyGestureStartedAsync(); + notifyGestureStarted(); setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */); if (mIsTransientTaskbar && !mTaskbarAlreadyOpen && !isLikelyToStartNewTask) { @@ -994,7 +995,7 @@ public abstract class AbsSwipeUpHandler, * Notifies the launcher that the swipe gesture has started. This can be called multiple times. */ @UiThread - private void notifyGestureStartedAsync() { + private void notifyGestureStarted() { final T curActivity = mActivity; if (curActivity != null) { // Once the gesture starts, we can no longer transition home through the button, so @@ -2063,8 +2064,8 @@ public abstract class AbsSwipeUpHandler, mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController, mRecentsAnimationTargets)); - // Disable scrolling in RecentsView for trackpad gestures. - if (!mGestureState.isTrackpadGesture()) { + // Disable scrolling in RecentsView for trackpad 3-finger swipe up gesture. + if (!mGestureState.isThreeFingerTrackpadGesture()) { mRecentsViewScrollLinked = true; } } @@ -2168,7 +2169,7 @@ public abstract class AbsSwipeUpHandler, ActiveGestureLog.INSTANCE.addLog("Unexpected task appeared" + " id=" + taskInfo.taskId + " pkg=" + taskInfo.baseIntent.getComponent().getPackageName()); - finishRecentsAnimationOnTasksAppeared(); + finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */); } else if (handleTaskAppeared(appearedTaskTargets)) { Optional taskTargetOptional = Arrays.stream(appearedTaskTargets) @@ -2176,17 +2177,22 @@ public abstract class AbsSwipeUpHandler, targetCompat.taskId == mGestureState.getLastStartedTaskId()) .findFirst(); if (!taskTargetOptional.isPresent()) { - finishRecentsAnimationOnTasksAppeared(); + finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */); return; } RemoteAnimationTarget taskTarget = taskTargetOptional.get(); TaskView taskView = mRecentsView.getTaskViewByTaskId(taskTarget.taskId); if (taskView == null || !taskView.getThumbnail().shouldShowSplashView()) { - finishRecentsAnimationOnTasksAppeared(); + finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */); return; } ViewGroup splashView = mActivity.getDragLayer(); + final QuickstepLauncher quickstepLauncher = mActivity instanceof QuickstepLauncher + ? (QuickstepLauncher) mActivity : null; + if (quickstepLauncher != null) { + quickstepLauncher.getDepthController().pauseBlursOnWindows(true); + } // When revealing the app with launcher splash screen, make the app visible // and behind the splash view before the splash is animated away. @@ -2194,7 +2200,7 @@ public abstract class AbsSwipeUpHandler, new SurfaceTransactionApplier(splashView); SurfaceTransaction transaction = new SurfaceTransaction(); for (RemoteAnimationTarget target : appearedTaskTargets) { - transaction.forSurface(target.leash).setAlpha(1).setLayer(-1); + transaction.forSurface(target.leash).setAlpha(1).setLayer(-1).setShow(); } surfaceApplier.scheduleApply(transaction); @@ -2206,16 +2212,25 @@ public abstract class AbsSwipeUpHandler, new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - finishRecentsAnimationOnTasksAppeared(); + // Hiding launcher which shows the app surface behind, then + // finishing recents to the app. After transition finish, showing + // the views on launcher again, so it can be visible when next + // animation starts. + splashView.setAlpha(0); + if (quickstepLauncher != null) { + quickstepLauncher.getDepthController() + .pauseBlursOnWindows(false); + } + finishRecentsAnimationOnTasksAppeared(() -> splashView.setAlpha(1)); } }); } } } - private void finishRecentsAnimationOnTasksAppeared() { + private void finishRecentsAnimationOnTasksAppeared(Runnable onFinishComplete) { if (mRecentsAnimationController != null) { - mRecentsAnimationController.finish(false /* toRecents */, null /* onFinishComplete */); + mRecentsAnimationController.finish(false /* toRecents */, onFinishComplete); } ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimationOnTasksAppeared"); } diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 2b0623a67d..02f9f57ec2 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -15,6 +15,9 @@ */ package com.android.quickstep; +import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe; +import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe; +import static com.android.launcher3.MotionEventsUtils.isTrackpadThreeFingerSwipe; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW; @@ -27,6 +30,7 @@ import android.annotation.Nullable; import android.annotation.TargetApi; import android.content.Intent; import android.os.Build; +import android.view.MotionEvent; import android.view.RemoteAnimationTarget; import com.android.launcher3.statemanager.BaseState; @@ -139,8 +143,30 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL private final BaseActivityInterface mActivityInterface; private final MultiStateCallback mStateCallback; private final int mGestureId; - private boolean mIsTrackpadGesture; + public enum TrackpadGestureType { + NONE, + // Assigned before we know whether it's a 3-finger or 4-finger gesture. + MULTI_FINGER, + THREE_FINGER, + FOUR_FINGER; + + public static TrackpadGestureType getTrackpadGestureType(MotionEvent event) { + if (!isTrackpadMultiFingerSwipe(event)) { + return TrackpadGestureType.NONE; + } + if (isTrackpadThreeFingerSwipe(event)) { + return TrackpadGestureType.THREE_FINGER; + } + if (isTrackpadFourFingerSwipe(event)) { + return TrackpadGestureType.FOUR_FINGER; + } + + return TrackpadGestureType.MULTI_FINGER; + } + } + + private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE; private CachedTaskInfo mRunningTask; private GestureEndTarget mEndTarget; private RemoteAnimationTarget mLastAppearedTaskTarget; @@ -249,17 +275,22 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL } /** - * Sets if the gesture is is from the trackpad. + * Sets if the gesture is is from the trackpad, if so, whether 3-finger, or 4-finger */ - public void setIsTrackpadGesture(boolean isTrackpadGesture) { - mIsTrackpadGesture = isTrackpadGesture; + public void setTrackpadGestureType(TrackpadGestureType trackpadGestureType) { + mTrackpadGestureType = trackpadGestureType; } - /** - * @return if the gesture is from the trackpad. - */ public boolean isTrackpadGesture() { - return mIsTrackpadGesture; + return mTrackpadGestureType != TrackpadGestureType.NONE; + } + + public boolean isThreeFingerTrackpadGesture() { + return mTrackpadGestureType == TrackpadGestureType.THREE_FINGER; + } + + public boolean isFourFingerTrackpadGesture() { + return mTrackpadGestureType == TrackpadGestureType.FOUR_FINGER; } /** diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index 3979444499..c18ad5a626 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -141,8 +141,8 @@ public class LauncherBackAnimationController { @Override public void onBackCancelled() { handler.post(() -> { - resetPositionAnimated(); - mProgressAnimator.reset(); + mProgressAnimator.onBackCancelled( + LauncherBackAnimationController.this::resetPositionAnimated); }); } @@ -192,7 +192,7 @@ public class LauncherBackAnimationController { } @Override - public void onAnimationCancelled(boolean isKeyguardOccluded) {} + public void onAnimationCancelled() {} }; SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback, runner); diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index fbe2778fdb..07db194ff4 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -249,7 +249,7 @@ public class OverviewCommandHelper { } GestureState gestureState = mService.createGestureState(GestureState.DEFAULT_STATE, - false /* isTrackpadGesture */); + GestureState.TrackpadGestureType.NONE); gestureState.setHandlingAtomicEvent(true); AbsSwipeUpHandler interactionHandler = mService.getSwipeUpHandlerFactory() .newHandler(gestureState, cmd.createTime); diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 5391f4d46c..5df4734eee 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -125,6 +125,13 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { .getTaskbarAllAppsTopPadding()); } + case TestProtocol.REQUEST_TASKBAR_APPS_LIST_SCROLL_Y: { + return getTISBinderUIProperty(Bundle::putInt, tisBinder -> + tisBinder.getTaskbarManager() + .getCurrentActivityContext() + .getTaskbarAllAppsScroll()); + } + case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT: runOnTISBinder(tisBinder -> { enableBlockingTimeout(tisBinder, true); diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index 4adfae5ee8..f8e09e1e88 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -150,10 +150,17 @@ public class RecentsAnimationController { @UiThread public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) { - if (mFinishRequested) { - // If finishing, add to pending finish callbacks, otherwise, if finished, adding to the - // destroyed RunnableList will just trigger the callback to be called immediately - mPendingFinishCallbacks.add(callback); + finishController(toRecents, callback, sendUserLeaveHint, false /* forceFinish */); + } + + @UiThread + public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint, + boolean forceFinish) { + mPendingFinishCallbacks.add(callback); + if (!forceFinish && mFinishRequested) { + // If finish has already been requested, then add the callback to the pending list. + // If already finished, then adding it to the destroyed RunnableList will just + // trigger the callback to be called immediately return; } ActiveGestureLog.INSTANCE.addLog( @@ -165,15 +172,19 @@ public class RecentsAnimationController { mFinishRequested = true; mFinishTargetIsLauncher = toRecents; mOnFinishedListener.accept(this); - mPendingFinishCallbacks.add(callback); - UI_HELPER_EXECUTOR.execute(() -> { + Runnable finishCb = () -> { mController.finish(toRecents, sendUserLeaveHint); InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME); InteractionJankMonitorWrapper.end( InteractionJankMonitorWrapper.CUJ_APP_SWIPE_TO_RECENTS); MAIN_EXECUTOR.execute(mPendingFinishCallbacks::executeAllAndDestroy); - }); + }; + if (forceFinish) { + finishCb.run(); + } else { + UI_HELPER_EXECUTOR.execute(finishCb); + } } /** diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index 9a23557fdf..d3e4ce5db8 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -98,7 +98,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { private final ArrayList mOnDestroyActions = new ArrayList<>(); - private @SystemUiStateFlags int mSystemUiStateFlags; + private @SystemUiStateFlags int mSystemUiStateFlags = QuickStepContract.SYSUI_STATE_AWAKE; private NavigationMode mMode = THREE_BUTTONS; private NavBarPosition mNavBarPosition; diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 512d47e6c7..fdb30cedf3 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -967,7 +967,7 @@ public class SystemUiProxy implements ISystemUiProxy { IRemoteAnimationRunner runner) { mBackToLauncherCallback = callback; mBackToLauncherRunner = runner; - if (mBackAnimation == null) { + if (mBackAnimation == null || mBackToLauncherCallback == null) { return; } try { diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index c3c11977d3..c8c629233c 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -115,7 +115,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn } } // But force-finish it anyways - finishRunningRecentsAnimation(false /* toHome */); + finishRunningRecentsAnimation(false /* toHome */, true /* forceFinish */); if (mCallbacks != null) { // If mCallbacks still != null, that means we are getting this startRecentsAnimation() @@ -291,13 +291,26 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn * Finishes the running recents animation. */ public void finishRunningRecentsAnimation(boolean toHome) { + finishRunningRecentsAnimation(toHome, false /* forceFinish */); + } + + /** + * Finishes the running recents animation. + * @param forceFinish will synchronously finish the controller + */ + private void finishRunningRecentsAnimation(boolean toHome, boolean forceFinish) { if (mController != null) { ActiveGestureLog.INSTANCE.addLog( /* event= */ "finishRunningRecentsAnimation", toHome); mCallbacks.notifyAnimationCanceled(); - Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), toHome - ? mController::finishAnimationToHome - : mController::finishAnimationToApp); + if (forceFinish) { + mController.finishController(toHome, null, false /* sendUserLeaveHint */, + true /* forceFinish */); + } else { + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), toHome + ? mController::finishAnimationToHome + : mController::finishAnimationToApp); + } cleanUpRecentsAnimation(); } } diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index fd7b3434bd..813523888d 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -128,19 +128,19 @@ public interface TaskShortcutFactory { * A menu item, "Save app pair", that allows the user to preserve the current app combination as * a single persistent icon on the Home screen, allowing for quick split screen initialization. */ - class SaveAppPairSystemShortcut extends SystemShortcut { - + class SaveAppPairSystemShortcut extends SystemShortcut { private final TaskView mTaskView; - public SaveAppPairSystemShortcut(BaseDraggingActivity target, TaskView taskView) { - super(R.drawable.ic_save_app_pair, R.string.save_app_pair, target, + public SaveAppPairSystemShortcut(BaseDraggingActivity activity, TaskView taskView) { + super(R.drawable.ic_save_app_pair, R.string.save_app_pair, activity, taskView.getItemInfo(), taskView); mTaskView = taskView; } @Override public void onClick(View view) { - // TODO (b/274189428): Call "saveAppPair" function in new AppPairController class + ((RecentsView) mTarget.getOverviewPanel()) + .getSplitSelectController().getAppPairsController().saveAppPair(mTaskView); } } diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index f0d0bdb0ed..499a2601a9 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -243,7 +243,17 @@ public final class TaskViewUtils { TOUCH_RESPONSE_INTERPOLATOR); out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0, TOUCH_RESPONSE_INTERPOLATOR); - + out.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + super.onAnimationStart(animation); + final SurfaceTransaction showTransaction = new SurfaceTransaction(); + for (int i = targets.apps.length - 1; i >= 0; --i) { + showTransaction.getTransaction().show(targets.apps[i].leash); + } + applier.scheduleApply(showTransaction); + } + }); out.addOnFrameCallback(() -> { for (RemoteTargetHandle handle : remoteTargetHandles) { handle.getTaskViewSimulator().apply(handle.getTransformParams()); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 1cf682bffc..038c6743dd 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -24,11 +24,11 @@ import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE; -import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe; import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS; import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.GestureState.DEFAULT_STATE; +import static com.android.quickstep.GestureState.TrackpadGestureType.getTrackpadGestureType; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_MOVE; @@ -77,11 +77,11 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatedFloat; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.StatefulActivity; @@ -647,7 +647,7 @@ public class TouchInteractionService extends Service // onConsumerInactive and wipe the previous gesture state GestureState prevGestureState = new GestureState(mGestureState); GestureState newGestureState = createGestureState(mGestureState, - isTrackpadMultiFingerSwipe(event)); + getTrackpadGestureType(event)); newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis()); mConsumer.onConsumerAboutToBeSwitched(); mGestureState = newGestureState; @@ -656,7 +656,7 @@ public class TouchInteractionService extends Service } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode() && mDeviceState.canTriggerAssistantAction(event)) { mGestureState = createGestureState(mGestureState, - isTrackpadMultiFingerSwipe(event)); + getTrackpadGestureType(event)); // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we // should not interrupt it. QuickSwitch assumes that interruption can only // happen if the next gesture is also quick switch. @@ -678,7 +678,9 @@ public class TouchInteractionService extends Service if (mUncheckedConsumer != InputConsumer.NO_OP) { switch (event.getActionMasked()) { - case ACTION_DOWN, ACTION_UP -> + case ACTION_DOWN: + // fall through + case ACTION_UP: ActiveGestureLog.INSTANCE.addLog( /* event= */ "onMotionEvent(" + (int) event.getRawX() + ", " + (int) event.getRawY() + "): " @@ -687,15 +689,18 @@ public class TouchInteractionService extends Service /* gestureEvent= */ event.getActionMasked() == ACTION_DOWN ? MOTION_DOWN : MOTION_UP); - case ACTION_MOVE -> + break; + case ACTION_MOVE: ActiveGestureLog.INSTANCE.addLog("onMotionEvent: " + MotionEvent.actionToString(event.getActionMasked()) + "," + MotionEvent.classificationToString(event.getClassification()) + ", pointerCount: " + event.getPointerCount(), MOTION_MOVE); - default -> + break; + default: { ActiveGestureLog.INSTANCE.addLog("onMotionEvent: " + MotionEvent.actionToString(event.getActionMasked()) + "," + MotionEvent.classificationToString(event.getClassification())); + } } } @@ -708,9 +713,13 @@ public class TouchInteractionService extends Service event.setAction(ACTION_CANCEL); } - // Skip ACTION_POINTER_DOWN and ACTION_POINTER_UP events from trackpad. - if (!mGestureState.isTrackpadGesture() || (action != ACTION_POINTER_DOWN - && action != ACTION_POINTER_UP)) { + if (mGestureState.isTrackpadGesture() && (action == ACTION_POINTER_DOWN + || action == ACTION_POINTER_UP)) { + // Skip ACTION_POINTER_DOWN and ACTION_POINTER_UP events from trackpad. + if (action == ACTION_POINTER_DOWN) { + mGestureState.setTrackpadGestureType(getTrackpadGestureType(event)); + } + } else { mUncheckedConsumer.onMotionEvent(event); } @@ -744,7 +753,7 @@ public class TouchInteractionService extends Service } public GestureState createGestureState(GestureState previousGestureState, - boolean isTrackpadGesture) { + GestureState.TrackpadGestureType trackpadGestureType) { final GestureState gestureState; TopTaskTracker.CachedTaskInfo taskInfo; if (mTaskAnimationManager.isRecentsAnimationRunning()) { @@ -761,7 +770,7 @@ public class TouchInteractionService extends Service taskInfo = TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false); gestureState.updateRunningTask(taskInfo); } - gestureState.setIsTrackpadGesture(isTrackpadGesture); + gestureState.setTrackpadGestureType(trackpadGestureType); // Log initial state for the gesture. ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=") @@ -835,12 +844,18 @@ public class TouchInteractionService extends Service // If Taskbar is present, we listen for long press to unstash it. TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext(); - if (tac != null && canStartSystemGesture) { - reasonString.append(NEWLINE_PREFIX) - .append(reasonPrefix) - .append(SUBSTRING_PREFIX) - .append("TaskbarActivityContext != null, using TaskbarStashInputConsumer"); - base = new TaskbarStashInputConsumer(this, base, mInputMonitorCompat, tac); + if (tac != null) { + // Present always on large screen or on small screen w/ flag + DeviceProfile dp = tac.getDeviceProfile(); + boolean useTaskbarConsumer = dp.isTaskbarPresent && !TaskbarManager.isPhoneMode(dp); + if (canStartSystemGesture && useTaskbarConsumer) { + reasonString.append(NEWLINE_PREFIX) + .append(reasonPrefix) + .append(SUBSTRING_PREFIX) + .append("TaskbarActivityContext != null, " + + "using TaskbarStashInputConsumer"); + base = new TaskbarStashInputConsumer(this, base, mInputMonitorCompat, tac); + } } if (mDeviceState.isBubblesExpanded()) { @@ -860,7 +875,6 @@ public class TouchInteractionService extends Service } if (ENABLE_TRACKPAD_GESTURE.get() && mGestureState.isTrackpadGesture() - && mGestureState.getActivityInterface().isResumed() && !previousGestureState.isRecentsAnimationRunning()) { reasonString = newCompoundString(reasonPrefix) .append(SUBSTRING_PREFIX) diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 601533d7e6..2dcbbb907a 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -203,8 +203,24 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } int edgeFlags = ev.getEdgeFlags(); ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR); - // Disable scrolling in RecentsView for trackpad gestures. - if (!mGestureState.isTrackpadGesture()) { + + if (mGestureState.isTrackpadGesture()) { + // Disable scrolling in RecentsView for 3-finger trackpad gesture. We don't know if a + // trackpad motion event is 3-finger or 4-finger with the U API until ACTION_MOVE (we + // skip ACTION_POINTER_UP events in TouchInteractionService), so in order to make sure + // that RecentsView always get a closed sequence of motion events and yet disable + // 3-finger scroll, we do the following (1) always dispatch ACTION_DOWN and ACTION_UP + // trackpad multi-finger motion events. (2) only dispatch 4-finger ACTION_MOVE motion + // events. + switch (ev.getActionMasked()) { + case ACTION_MOVE -> { + if (mGestureState.isFourFingerTrackpadGesture()) { + mRecentsViewDispatcher.dispatchEvent(ev); + } + } + default -> mRecentsViewDispatcher.dispatchEvent(ev); + } + } else { mRecentsViewDispatcher.dispatchEvent(ev); } ev.setEdgeFlags(edgeFlags); @@ -294,8 +310,14 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC boolean haveNotPassedSlopOnContinuedGesture = !mPassedSlopOnThisGesture && mPassedPilferInputSlop; double degrees = Math.toDegrees(Math.atan(upDist / horizontalDist)); - boolean isLikelyToStartNewTask = haveNotPassedSlopOnContinuedGesture - || degrees <= OVERVIEW_MIN_DEGREES; + + // Regarding degrees >= -OVERVIEW_MIN_DEGREES - Trackpad gestures can start anywhere + // on the screen, allowing downward swipes. We want to impose the same angle in that + // scenario. + boolean swipeWithinQuickSwitchRange = degrees <= OVERVIEW_MIN_DEGREES + && (!mGestureState.isTrackpadGesture() || degrees >= -OVERVIEW_MIN_DEGREES); + boolean isLikelyToStartNewTask = + haveNotPassedSlopOnContinuedGesture || swipeWithinQuickSwitchRange; if (!mPassedPilferInputSlop) { if (passedSlop) { @@ -306,9 +328,12 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // Do not allow quick switch for trackpad 3-finger gestures // TODO(b/261815244): might need to impose stronger conditions for the swipe // angle - boolean noQuickSwitchForTrackpadGesture = mGestureState.isTrackpadGesture() - && isLikelyToStartNewTask; - if (isHorizontalSwipeWhenDisabled || noQuickSwitchForTrackpadGesture) { + boolean noQuickSwitchForThreeFingerGesture = isLikelyToStartNewTask + && mGestureState.isThreeFingerTrackpadGesture(); + boolean noQuickstepForFourFingerGesture = !isLikelyToStartNewTask + && mGestureState.isFourFingerTrackpadGesture(); + if (isHorizontalSwipeWhenDisabled || noQuickSwitchForThreeFingerGesture + || noQuickstepForFourFingerGesture) { forceCancelGesture(ev); break; } diff --git a/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java index f3d2a60b15..898aa8640d 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java @@ -33,6 +33,7 @@ public class StatusBarInputConsumer extends DelegateInputConsumer { private final SystemUiProxy mSystemUiProxy; private final float mTouchSlop; private final PointF mDown = new PointF(); + private boolean mHasPassedTouchSlop; public StatusBarInputConsumer(Context context, InputConsumer delegate, InputMonitorCompat inputMonitor) { @@ -53,13 +54,21 @@ public class StatusBarInputConsumer extends DelegateInputConsumer { mDelegate.onMotionEvent(ev); switch (ev.getActionMasked()) { - case ACTION_DOWN -> mDown.set(ev.getX(), ev.getY()); + case ACTION_DOWN -> { + mDown.set(ev.getX(), ev.getY()); + mHasPassedTouchSlop = false; + } case ACTION_MOVE -> { - float displacementY = ev.getY() - mDown.y; - if (displacementY > mTouchSlop) { - setActive(ev); - ev.setAction(ACTION_DOWN); - dispatchTouchEvent(ev); + if (!mHasPassedTouchSlop) { + float displacementY = ev.getY() - mDown.y; + if (Math.abs(displacementY) > mTouchSlop) { + mHasPassedTouchSlop = true; + if (displacementY > 0) { + setActive(ev); + ev.setAction(ACTION_DOWN); + dispatchTouchEvent(ev); + } + } } } } diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java index 79971de0e8..8274a51ff7 100644 --- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java @@ -26,6 +26,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; @@ -63,11 +64,13 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.util.Executors; import com.android.quickstep.GestureState; import com.android.quickstep.TouchInteractionService.TISBinder; +import com.android.quickstep.util.LottieAnimationColorUtils; import com.android.quickstep.util.TISBindHelper; import com.airbnb.lottie.LottieAnimationView; import java.net.URISyntaxException; +import java.util.Map; /** * A page shows after SUW flow to hint users to swipe up from the bottom of the screen to go home @@ -82,6 +85,9 @@ public class AllSetActivity extends Activity { private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "suwColorAccentLight"; private static final String EXTRA_DEVICE_NAME = "suwDeviceName"; + private static final String LOTTIE_PRIMARY_COLOR_TOKEN = ".primary"; + private static final String LOTTIE_TERTIARY_COLOR_TOKEN = ".tertiary"; + private static final float HINT_BOTTOM_FACTOR = 1 - .94f; private static final int MAX_SWIPE_DURATION = 350; @@ -114,7 +120,8 @@ public class AllSetActivity extends Activity { | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); - int mode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + Resources resources = getResources(); + int mode = resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES; Intent intent = getIntent(); int accentColor = intent.getIntExtra( @@ -126,7 +133,7 @@ public class AllSetActivity extends Activity { mBackground = new BgDrawable(this); findViewById(R.id.root_view).setBackground(mBackground); mContentView = findViewById(R.id.content_view); - mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift); + mSwipeUpShift = resources.getDimension(R.dimen.allset_swipe_up_shift); TextView subtitle = findViewById(R.id.subtitle); String suwDeviceName = intent.getStringExtra(EXTRA_DEVICE_NAME); @@ -188,8 +195,15 @@ public class AllSetActivity extends Activity { // There's a bug in the currently used external Lottie library (v5.2.0), and it doesn't load // the correct animation from the raw resources when configuration changes, so we need to // manually load the resource and pass it to Lottie. - mAnimatedBackground.setAnimation(getResources().openRawResource(R.raw.all_set_page_bg), + mAnimatedBackground.setAnimation(resources.openRawResource(R.raw.all_set_page_bg), null); + + LottieAnimationColorUtils.updateColors( + mAnimatedBackground, + Map.of(LOTTIE_PRIMARY_COLOR_TOKEN, R.color.all_set_bg_primary, + LOTTIE_TERTIARY_COLOR_TOKEN, R.color.all_set_bg_tertiary), + getTheme()); + startBackgroundAnimation(); } diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java index 6f50e3e4a5..67a0756646 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java @@ -233,13 +233,19 @@ abstract class TutorialController implements BackGestureAttemptCallback, @LayoutRes protected int getMockHotseatResId() { - return mTutorialFragment.isLargeScreen() - ? (mTutorialFragment.isFoldable() + if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) { + return mTutorialFragment.isLargeScreen() + ? mTutorialFragment.isFoldable() + ? R.layout.redesigned_gesture_tutorial_foldable_mock_hotseat + : R.layout.redesigned_gesture_tutorial_tablet_mock_hotseat + : R.layout.redesigned_gesture_tutorial_mock_hotseat; + } else { + return mTutorialFragment.isLargeScreen() + ? mTutorialFragment.isFoldable() ? R.layout.gesture_tutorial_foldable_mock_hotseat - : R.layout.gesture_tutorial_tablet_mock_hotseat) - : (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get() - ? R.layout.redesigned_gesture_tutorial_mock_hotseat - : R.layout.gesture_tutorial_mock_hotseat); + : R.layout.gesture_tutorial_tablet_mock_hotseat + : R.layout.gesture_tutorial_mock_hotseat; + } } @LayoutRes diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java new file mode 100644 index 0000000000..cbde257003 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java @@ -0,0 +1,104 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.quickstep.util; + +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + +import android.content.Context; + +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; +import com.android.launcher3.icons.IconCache; +import com.android.launcher3.model.data.FolderInfo; +import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.quickstep.views.TaskView; + +/** + * Mini controller class that handles app pair interactions: saving, modifying, deleting, etc. + */ +public class AppPairsController { + + private static final int POINT_THREE_RATIO = 0; + private static final int POINT_FIVE_RATIO = 1; + private static final int POINT_SEVEN_RATIO = 2; + /** + * Used to calculate {@link #complement(int)} + */ + private static final int FULL_RATIO = 2; + + private static final int LEFT_TOP = 0; + private static final int RIGHT_BOTTOM = 1 << 2; + + // TODO (jeremysim b/274189428): Support saving different ratios in future. + public int DEFAULT_RATIO = POINT_FIVE_RATIO; + + private final Context mContext; + private final SplitSelectStateController mSplitSelectStateController; + public AppPairsController(Context context, + SplitSelectStateController splitSelectStateController) { + mContext = context; + mSplitSelectStateController = splitSelectStateController; + } + + /** + * Creates a new app pair ItemInfo and adds it to the workspace + */ + public void saveAppPair(TaskView taskView) { + TaskView.TaskIdAttributeContainer[] attributes = taskView.getTaskIdAttributeContainers(); + WorkspaceItemInfo app1 = attributes[0].getItemInfo().clone(); + WorkspaceItemInfo app2 = attributes[1].getItemInfo().clone(); + app1.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; + app2.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; + app1.rank = DEFAULT_RATIO + LEFT_TOP; + app2.rank = complement(DEFAULT_RATIO) + RIGHT_BOTTOM; + FolderInfo newAppPair = FolderInfo.createAppPair(app1, app2); + // TODO (jeremysim b/274189428): Generate default title here. + newAppPair.title = "App pair 1"; + + IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache(); + MODEL_EXECUTOR.execute(() -> { + newAppPair.contents.forEach(member -> { + member.title = ""; + member.bitmap = iconCache.getDefaultIcon(newAppPair.user); + iconCache.getTitleAndIcon(member, member.usingLowResIcon()); + }); + MAIN_EXECUTOR.execute(() -> { + LauncherAccessibilityDelegate delegate = + Launcher.getLauncher(mContext).getAccessibilityDelegate(); + if (delegate != null) { + MAIN_EXECUTOR.execute(() -> delegate.addToWorkspace(newAppPair, true)); + } + }); + }); + + } + + /** + * Used to calculate the "opposite" side of the split ratio, so we can know how big the split + * apps are supposed to be. This math works because POINT_THREE_RATIO is internally represented + * by 0, POINT_FIVE_RATIO is represented by 1, and POINT_SEVEN_RATIO is represented by 2. There + * are no other supported ratios for now. + */ + private int complement(int ratio1) { + int ratio2 = FULL_RATIO - ratio1; + return ratio2; + } +} diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java index cecf58d105..b5c582a3e0 100644 --- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java +++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java @@ -74,6 +74,10 @@ public class BaseDepthController { // Hints that there is potentially content behind Launcher and that we shouldn't optimize by // marking the launcher surface as opaque. Only used in certain Launcher states. private boolean mHasContentBehindLauncher; + + /** Pause applying depth and blur, can be used when something behind the Launcher. */ + protected boolean mPauseBlurs; + /** * Last blur value, in pixels, that was applied. * For debugging purposes. @@ -104,6 +108,13 @@ public class BaseDepthController { mHasContentBehindLauncher = hasContentBehindLauncher; } + public void pauseBlursOnWindows(boolean pause) { + if (pause != mPauseBlurs) { + mPauseBlurs = pause; + applyDepthAndBlur(); + } + } + protected void applyDepthAndBlur() { float depth = mDepth; IBinder windowToken = mLauncher.getRootView().getWindowToken(); @@ -121,9 +132,9 @@ public class BaseDepthController { return; } boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque(); - boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg; + boolean isSurfaceOpaque = mPauseBlurs || (!mHasContentBehindLauncher && hasOpaqueBg); - mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg + mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg || mPauseBlurs ? 0 : (int) (depth * mMaxBlurRadius); SurfaceControl.Transaction transaction = new SurfaceControl.Transaction() .setBackgroundBlurRadius(mSurface, mCurrentBlur) diff --git a/quickstep/src/com/android/quickstep/util/BorderAnimator.java b/quickstep/src/com/android/quickstep/util/BorderAnimator.java index 1f1c15bdb8..c43fb27f05 100644 --- a/quickstep/src/com/android/quickstep/util/BorderAnimator.java +++ b/quickstep/src/com/android/quickstep/util/BorderAnimator.java @@ -16,17 +16,18 @@ package com.android.quickstep.util; import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.annotation.ColorInt; import android.annotation.Nullable; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; +import android.view.View; import android.view.animation.Interpolator; import androidx.annotation.NonNull; import androidx.annotation.Px; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatedFloat; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.Interpolators; @@ -35,7 +36,9 @@ import com.android.launcher3.anim.Interpolators; * Utility class for drawing a rounded-rect border around a view. *

* To use this class: - * 1. Create an instance in the target view. + * 1. Create an instance in the target view. NOTE: The border will animate outwards from the + * provided border bounds. If the border will not be visible outside of those bounds, then a + * {@link ViewScaleTargetProvider} must be provided in the constructor. * 2. Override the target view's {@link android.view.View#draw(Canvas)} method and call * {@link BorderAnimator#drawBorder(Canvas)} after {@code super.draw(canvas)}. * 3. Call {@link BorderAnimator#buildAnimator(boolean)} and start the animation or call @@ -56,12 +59,13 @@ public final class BorderAnimator { @Px private final int mBorderWidthPx; @Px private final int mBorderRadiusPx; @NonNull private final Runnable mInvalidateViewCallback; + @Nullable private final ViewScaleTargetProvider mViewScaleTargetProvider; private final long mAppearanceDurationMs; private final long mDisappearanceDurationMs; @NonNull private final Interpolator mInterpolator; @NonNull private final Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - private int mAlignmentAdjustment; + private float mAlignmentAdjustment; @Nullable private Animator mRunningBorderAnimation; @@ -76,6 +80,22 @@ public final class BorderAnimator { borderRadiusPx, borderColor, invalidateViewCallback, + /* viewScaleTargetProvider= */ null); + } + + public BorderAnimator( + @NonNull BorderBoundsBuilder borderBoundsBuilder, + int borderWidthPx, + int borderRadiusPx, + @ColorInt int borderColor, + @NonNull Runnable invalidateViewCallback, + @Nullable ViewScaleTargetProvider viewScaleTargetProvider) { + this(borderBoundsBuilder, + borderWidthPx, + borderRadiusPx, + borderColor, + invalidateViewCallback, + viewScaleTargetProvider, DEFAULT_APPEARANCE_ANIMATION_DURATION_MS, DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS, DEFAULT_INTERPOLATOR); @@ -87,6 +107,7 @@ public final class BorderAnimator { int borderRadiusPx, @ColorInt int borderColor, @NonNull Runnable invalidateViewCallback, + @Nullable ViewScaleTargetProvider viewScaleTargetProvider, long appearanceDurationMs, long disappearanceDurationMs, @NonNull Interpolator interpolator) { @@ -94,6 +115,7 @@ public final class BorderAnimator { mBorderWidthPx = borderWidthPx; mBorderRadiusPx = borderRadiusPx; mInvalidateViewCallback = invalidateViewCallback; + mViewScaleTargetProvider = viewScaleTargetProvider; mAppearanceDurationMs = appearanceDurationMs; mDisappearanceDurationMs = disappearanceDurationMs; mInterpolator = interpolator; @@ -106,16 +128,14 @@ public final class BorderAnimator { private void updateOutline() { float interpolatedProgress = mInterpolator.getInterpolation( mBorderAnimationProgress.value); - mAlignmentAdjustment = (int) Utilities.mapBoundToRange( - mBorderAnimationProgress.value, - /* lowerBound= */ 0f, - /* upperBound= */ 1f, - /* toMin= */ 0f, - /* toMax= */ (float) (mBorderWidthPx / 2f), - mInterpolator); + float borderWidth = mBorderWidthPx * interpolatedProgress; + // Outset the border by half the width to create an outwards-growth animation + mAlignmentAdjustment = (-borderWidth / 2f) + // Inset the border if we are scaling the container up + + (mViewScaleTargetProvider == null ? 0 : mBorderWidthPx); mBorderPaint.setAlpha(Math.round(255 * interpolatedProgress)); - mBorderPaint.setStrokeWidth(Math.round(mBorderWidthPx * interpolatedProgress)); + mBorderPaint.setStrokeWidth(borderWidth); mInvalidateViewCallback.run(); } @@ -126,13 +146,16 @@ public final class BorderAnimator { * calling super. */ public void drawBorder(Canvas canvas) { + // Increase the radius if we are scaling the container up + float radiusAdjustment = mViewScaleTargetProvider == null + ? -mAlignmentAdjustment : mAlignmentAdjustment; canvas.drawRoundRect( /* left= */ mBorderBounds.left + mAlignmentAdjustment, /* top= */ mBorderBounds.top + mAlignmentAdjustment, /* right= */ mBorderBounds.right - mAlignmentAdjustment, /* bottom= */ mBorderBounds.bottom - mAlignmentAdjustment, - /* rx= */ mBorderRadiusPx - mAlignmentAdjustment, - /* ry= */ mBorderRadiusPx - mAlignmentAdjustment, + /* rx= */ mBorderRadiusPx + radiusAdjustment, + /* ry= */ mBorderRadiusPx + radiusAdjustment, /* paint= */ mBorderPaint); } @@ -146,22 +169,81 @@ public final class BorderAnimator { mRunningBorderAnimation.setDuration( isAppearing ? mAppearanceDurationMs : mDisappearanceDurationMs); + mRunningBorderAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + setViewScales(); + } + }); mRunningBorderAnimation.addListener( - AnimatorListeners.forEndCallback(() -> mRunningBorderAnimation = null)); + AnimatorListeners.forEndCallback(() -> { + mRunningBorderAnimation = null; + if (isAppearing) { + return; + } + resetViewScales(); + })); return mRunningBorderAnimation; } /** * Immediately shows/hides the border without an animation. - * + *

* To animate the appearance/disappearance, see {@link BorderAnimator#buildAnimator(boolean)} */ public void setBorderVisible(boolean visible) { if (mRunningBorderAnimation != null) { mRunningBorderAnimation.end(); } + mBorderBoundsBuilder.updateBorderBounds(mBorderBounds); + if (visible) { + setViewScales(); + } mBorderAnimationProgress.updateValue(visible ? 1f : 0f); + if (!visible) { + resetViewScales(); + } + } + + private void setViewScales() { + if (mViewScaleTargetProvider == null) { + return; + } + View container = mViewScaleTargetProvider.getContainerView(); + float width = container.getWidth(); + float height = container.getHeight(); + // scale up just enough to make room for the border + float scaleX = 1f + ((2 * mBorderWidthPx) / width); + float scaleY = 1f + ((2 * mBorderWidthPx) / height); + + container.setPivotX(width / 2); + container.setPivotY(height / 2); + container.setScaleX(scaleX); + container.setScaleY(scaleY); + + View contentView = mViewScaleTargetProvider.getContentView(); + contentView.setPivotX(contentView.getWidth() / 2f); + contentView.setPivotY(contentView.getHeight() / 2f); + contentView.setScaleX(1f / scaleX); + contentView.setScaleY(1f / scaleY); + } + + private void resetViewScales() { + if (mViewScaleTargetProvider == null) { + return; + } + View container = mViewScaleTargetProvider.getContainerView(); + container.setPivotX(container.getWidth()); + container.setPivotY(container.getHeight()); + container.setScaleX(1f); + container.setScaleY(1f); + + View contentView = mViewScaleTargetProvider.getContentView(); + contentView.setPivotX(contentView.getWidth() / 2f); + contentView.setPivotY(contentView.getHeight() / 2f); + contentView.setScaleX(1f); + contentView.setScaleY(1f); } /** @@ -174,4 +256,25 @@ public final class BorderAnimator { */ void updateBorderBounds(Rect rect); } + + /** + * Provider for scaling target views for the beginning and end of this animation. + */ + public interface ViewScaleTargetProvider { + + /** + * Returns the content view's container. This view will be scaled up to make room for the + * border. + */ + @NonNull + View getContainerView(); + + /** + * Returns the content view. This view will be scaled down reciprocally to the container's + * up-scaling to maintain its original size. This should be the view containing all of the + * content being surrounded by the border. + */ + @NonNull + View getContentView(); + } } diff --git a/quickstep/src/com/android/quickstep/util/LottieAnimationColorUtils.java b/quickstep/src/com/android/quickstep/util/LottieAnimationColorUtils.java new file mode 100644 index 0000000000..f98b04bf54 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/LottieAnimationColorUtils.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import static com.airbnb.lottie.LottieProperty.COLOR_FILTER; + +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.airbnb.lottie.LottieAnimationView; +import com.airbnb.lottie.model.KeyPath; + +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** Utility class for programmatically updating Lottie animation tokenized colors. */ +public final class LottieAnimationColorUtils { + + private LottieAnimationColorUtils() {} + + /** + * Updates the given Lottie animation's tokenized colors according to the given mapping. + *

+ * Use this method signature only when {@code tokenToColorCodeMap} maps to packed ARBG color + * integers. + *

+ * @param animationView {@link LottieAnimationView} whose animation's colors need to be updated + * @param tokenToColorCodeMap A mapping from the color tokens used in the Lottie file used in + * {@code animationView} to packed ARBG color integers. + */ + public static void updateColors( + @NonNull LottieAnimationView animationView, + @NonNull Map tokenToColorCodeMap) { + updateColors(animationView, tokenToColorCodeMap, null); + } + + /** + * Updates the given Lottie animation's tokenized colors according to the given mapping. + *

+ * Use this method signature with a non-null theme only when {@code tokenToColorCodeMap} maps + * to color resource references. + *

+ * @param animationView {@link LottieAnimationView} whose animation's colors need to be updated + * @param tokenToColorCodeMap A mapping from the color tokens used in the Lottie file used in + * {@code animationView} to packed ARBG color integers or color + * resource references. + * @param theme {@link Theme} to be used when resolving color resource references. {@code null} + * iff {@code tokenToColorCodeMap} maps to packed ARBG color integers. + */ + public static void updateColors( + @NonNull LottieAnimationView animationView, + @NonNull Map tokenToColorCodeMap, + @Nullable Theme theme) { + Resources resources = animationView.getResources(); + final Map tokenToColorMap = theme == null + // tokenToColorCodeMap maps directly to ARBG values + ? tokenToColorCodeMap + // tokenToColorCodeMap maps to color references, build a mapping to resolved colors + : tokenToColorCodeMap.keySet().stream().collect(Collectors.toMap( + Function.identity(), + token -> resources.getColor(tokenToColorCodeMap.get(token), theme))); + + animationView.addLottieOnCompositionLoadedListener( + composition -> tokenToColorMap.forEach( + (token, color) -> animationView.addValueCallback( + new KeyPath("**", token, "**"), + COLOR_FILTER, + frameInfo -> new PorterDuffColorFilter( + color, PorterDuff.Mode.SRC_ATOP)))); + } +} diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index d44d7f637d..8b21115f0f 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -84,6 +84,7 @@ public class SplitSelectStateController { private final Handler mHandler; private final RecentsModel mRecentTasksModel; private final SplitAnimationController mSplitAnimationController; + private final AppPairsController mAppPairsController; private StatsLogManager mStatsLogManager; private final SystemUiProxy mSystemUiProxy; private final StateManager mStateManager; @@ -97,8 +98,15 @@ public class SplitSelectStateController { private UserHandle mInitialUser; private int mInitialTaskId = INVALID_TASK_ID; /** {@link #mSecondTaskIntent} and {@link #mSecondUser} (the user of the Intent) are set - * together when split is confirmed with an Intent. */ + * together when split is confirmed with an Intent. Either this or {@link #mSecondPendingIntent} + * will be set, but not both + */ private Intent mSecondTaskIntent; + /** + * Set when split is confirmed via a widget. Either this or {@link #mSecondTaskIntent} will be + * set, but not both + */ + private PendingIntent mSecondPendingIntent; private UserHandle mSecondUser; private int mSecondTaskId = INVALID_TASK_ID; private boolean mRecentsAnimationRunning; @@ -128,6 +136,7 @@ public class SplitSelectStateController { mDepthController = depthController; mRecentTasksModel = recentsModel; mSplitAnimationController = new SplitAnimationController(this); + mAppPairsController = new AppPairsController(context, this); } /** @@ -246,6 +255,16 @@ public class SplitSelectStateController { mSecondUser = user; } + /** + * To be called as soon as user selects the second app (even if animations aren't complete) + * Sets {@link #mSecondUser} from that of the pendingIntent + * @param pendingIntent The second PendingIntent that will be launched. + */ + public void setSecondTask(PendingIntent pendingIntent) { + mSecondPendingIntent = pendingIntent; + mSecondUser = pendingIntent.getCreatorUserHandle(); + } + /** * To be called when we want to launch split pairs from an existing GroupedTaskView. */ @@ -290,17 +309,18 @@ public class SplitSelectStateController { if (freezeTaskList) { options1.setFreezeRecentTasksReordering(); } + boolean hasSecondaryPendingIntent = mSecondPendingIntent != null; if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { final RemoteSplitLaunchTransitionRunner animationRunner = new RemoteSplitLaunchTransitionRunner(taskId1, taskId2, callback); final RemoteTransition remoteTransition = new RemoteTransition(animationRunner, ActivityThread.currentActivityThread().getApplicationThread(), "LaunchSplitPair"); - if (intent1 == null && intent2 == null) { + if (intent1 == null && (intent2 == null && !hasSecondaryPendingIntent)) { mSystemUiProxy.startTasks(taskId1, options1.toBundle(), taskId2, null /* options2 */, stagePosition, splitRatio, remoteTransition, shellInstanceId); - } else if (intent2 == null) { + } else if (intent2 == null && !hasSecondaryPendingIntent) { launchIntentOrShortcut(intent1, mInitialUser, options1, taskId2, stagePosition, splitRatio, remoteTransition, shellInstanceId); } else if (intent1 == null) { @@ -310,7 +330,9 @@ public class SplitSelectStateController { } else { mSystemUiProxy.startIntents(getPendingIntent(intent1, mInitialUser), getShortcutInfo(intent1, mInitialUser), options1.toBundle(), - getPendingIntent(intent2, mSecondUser), + hasSecondaryPendingIntent + ? mSecondPendingIntent + : getPendingIntent(intent2, mSecondUser), getShortcutInfo(intent2, mSecondUser), null /* options2 */, stagePosition, splitRatio, remoteTransition, shellInstanceId); } @@ -321,11 +343,11 @@ public class SplitSelectStateController { animationRunner, 300, 150, ActivityThread.currentActivityThread().getApplicationThread()); - if (intent1 == null && intent2 == null) { + if (intent1 == null && (intent2 == null && !hasSecondaryPendingIntent)) { mSystemUiProxy.startTasksWithLegacyTransition(taskId1, options1.toBundle(), taskId2, null /* options2 */, stagePosition, splitRatio, adapter, shellInstanceId); - } else if (intent2 == null) { + } else if (intent2 == null && !hasSecondaryPendingIntent) { launchIntentOrShortcutLegacy(intent1, mInitialUser, options1, taskId2, stagePosition, splitRatio, adapter, shellInstanceId); } else if (intent1 == null) { @@ -336,7 +358,9 @@ public class SplitSelectStateController { mSystemUiProxy.startIntentsWithLegacyTransition( getPendingIntent(intent1, mInitialUser), getShortcutInfo(intent1, mInitialUser), options1.toBundle(), - getPendingIntent(intent2, mSecondUser), + hasSecondaryPendingIntent + ? mSecondPendingIntent + : getPendingIntent(intent2, mSecondUser), getShortcutInfo(intent2, mSecondUser), null /* options2 */, stagePosition, splitRatio, adapter, shellInstanceId); } @@ -374,7 +398,22 @@ public class SplitSelectStateController { } } + /** + * We treat launching by intents as grouped in two ways, + * If {@param intent} represents the first app, we always convert the intent to pending intent + * It it represents second app, either the second intent OR mSecondPendingIntent will be used + * convert second intent to a pendingIntent OR return mSecondPendingIntent as is + */ private PendingIntent getPendingIntent(Intent intent, UserHandle user) { + boolean isParamFirstIntent = intent != null && intent == mInitialTaskIntent; + if (!isParamFirstIntent && mSecondPendingIntent != null) { + // Because mSecondPendingIntent and mSecondTaskIntent can't both be set, we know we need + // to be using mSecondPendingIntent + return mSecondPendingIntent; + } + + // intent param must either be mInitialTaskIntent or mSecondTaskIntent, convert either to + // a new PendingIntent return intent == null ? null : (user != null ? PendingIntent.getActivityAsUser(mContext, 0, intent, FLAG_MUTABLE | FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT, null /* options */, user) @@ -517,7 +556,7 @@ public class SplitSelectStateController { } @Override - public void onAnimationCancelled(boolean isKeyguardOccluded) { + public void onAnimationCancelled() { postAsyncCallback(mHandler, () -> { if (mSuccessCallback != null) { // Launching legacy tasks while recents animation is running will always cause @@ -546,6 +585,7 @@ public class SplitSelectStateController { mSplitEvent = null; mAnimateCurrentTaskDismissal = false; mDismissingFromSplitPair = false; + mSecondPendingIntent = null; } /** @@ -577,7 +617,8 @@ public class SplitSelectStateController { } private boolean isSecondTaskIntentSet() { - return (mSecondTaskId != INVALID_TASK_ID || mSecondTaskIntent != null); + return (mSecondTaskId != INVALID_TASK_ID || mSecondTaskIntent != null + || mSecondPendingIntent != null); } public void setFirstFloatingTaskView(FloatingTaskView floatingTaskView) { @@ -587,4 +628,8 @@ public class SplitSelectStateController { public FloatingTaskView getFirstFloatingTaskView() { return mFirstFloatingTaskView; } + + public AppPairsController getAppPairsController() { + return mAppPairsController; + } } diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java index dd10c2da5d..148a45a386 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java +++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java @@ -21,9 +21,15 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSP import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.PendingIntent; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.view.View; @@ -55,14 +61,38 @@ public class SplitToWorkspaceController { R.dimen.multi_window_task_divider_size) / 2; } + /** + * Handles widget selection from staged split. + * @param view Original widget view + * @param pendingIntent Provided by widget via InteractionHandler + * @return {@code true} if we can attempt launch the widget into split, {@code false} otherwise + * to allow launcher to handle the click + */ + public boolean handleSecondWidgetSelectionForSplit(View view, PendingIntent pendingIntent) { + if (shouldIgnoreSecondSplitLaunch()) { + return false; + } + + // Convert original widgetView into bitmap to use for animation + // TODO(b/276361926) get the icon for this widget via PackageManager? + int width = view.getWidth(); + int height = view.getHeight(); + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + view.draw(canvas); + + mController.setSecondTask(pendingIntent); + + startWorkspaceAnimation(view, bitmap, null /*icon*/); + return true; + } + /** * Handles second app selection from stage split. If the item can't be opened in split or * it's not in stage split state, we pass it onto Launcher's default item click handler. */ public boolean handleSecondAppSelectionForSplit(View view) { - if ((!ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS.get() - && !ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) - || !mController.isSplitSelectActive()) { + if (shouldIgnoreSecondSplitLaunch()) { return false; } Object tag = view.getTag(); @@ -86,6 +116,12 @@ public class SplitToWorkspaceController { mController.setSecondTask(intent, user); + startWorkspaceAnimation(view, null /*bitmap*/, bitmapInfo.newIcon(mLauncher)); + return true; + } + + private void startWorkspaceAnimation(@NonNull View view, @Nullable Bitmap bitmap, + @Nullable Drawable icon) { boolean isTablet = mLauncher.getDeviceProfile().isTablet; SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet); PendingAnimation pendingAnimation = new PendingAnimation(timings.getDuration()); @@ -107,8 +143,7 @@ public class SplitToWorkspaceController { false /* fadeWithThumbnail */, true /* isStagedTask */); FloatingTaskView secondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mLauncher, - view, null /* thumbnail */, bitmapInfo.newIcon(mLauncher), - secondTaskStartingBounds); + view, bitmap, icon, secondTaskStartingBounds); secondFloatingTaskView.setAlpha(1); secondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds, secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */); @@ -138,6 +173,11 @@ public class SplitToWorkspaceController { } }); pendingAnimation.buildAnim().start(); - return true; + } + + private boolean shouldIgnoreSecondSplitLaunch() { + return (!ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS.get() + && !ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) + || !mController.isSplitSelectActive(); } } diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java index 7ab285dfa7..441f88d115 100644 --- a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java +++ b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java @@ -106,6 +106,15 @@ public class SurfaceTransaction { mTransaction.setShadowRadius(mSurface, radius); return this; } + + /** + * Requests to show the given surface. + * @return this Builder + */ + public SurfaceProperties setShow() { + mTransaction.show(mSurface); + return this; + } } /** diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index cf6ee2d2e5..f0afa69983 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1192,6 +1192,17 @@ public abstract class RecentsView= 0; --i) { + showTransaction.getTransaction().show(apps[i].leash); + } + surfaceApplier.scheduleApply(showTransaction); + } + }); anim.play(appAnimator); anim.addListener(new AnimatorListenerAdapter() { @Override diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt index 428bd95159..8ee0fbb671 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt @@ -77,10 +77,10 @@ class TaskMenuViewWithArrow : ArrowPopup { shouldScaleArrow = true mIsArrowRotated = true // This synchronizes the arrow and menu to open at the same time - OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY - OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION - CLOSE_FADE_START_DELAY = CLOSE_CHILD_FADE_START_DELAY - CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION + mOpenChildFadeStartDelay = mOpenFadeStartDelay + mOpenChildFadeDuration = mOpenFadeDuration + mCloseFadeStartDelay = mCloseChildFadeStartDelay + mCloseFadeDuration = mCloseChildFadeDuration } private var alignedOptionIndex: Int = 0 @@ -213,7 +213,7 @@ class TaskMenuViewWithArrow : ArrowPopup { scrim?.let { anim.play( ObjectAnimator.ofFloat(it, View.ALPHA, 0f, scrimAlpha) - .setDuration(OPEN_DURATION.toLong()) + .setDuration(mOpenDuration.toLong()) ) } } @@ -222,7 +222,7 @@ class TaskMenuViewWithArrow : ArrowPopup { scrim?.let { anim.play( ObjectAnimator.ofFloat(it, View.ALPHA, scrimAlpha, 0f) - .setDuration(CLOSE_DURATION.toLong()) + .setDuration(mCloseDuration.toLong()) ) } } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 42589ced5d..53660b5040 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -581,6 +581,7 @@ public class TaskView extends FrameLayout implements Reusable { mIconView, STAGE_POSITION_UNDEFINED); mSnapshotView.bind(task); setOrientationState(orientedState); + mDigitalWellBeingToast.initialize(mTask); } /** @@ -984,10 +985,7 @@ public class TaskView extends FrameLayout implements Reusable { } if (needsUpdate(changes, FLAG_UPDATE_ICON)) { mIconLoadRequest = iconCache.updateIconInBackground(mTask, - (task) -> { - setIcon(mIconView, task.icon); - mDigitalWellBeingToast.initialize(mTask); - }); + (task) -> setIcon(mIconView, task.icon)); } } else { if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) { diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt index 3bf4ad38c3..20466ad844 100644 --- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt +++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt @@ -53,6 +53,7 @@ abstract class TaskbarBaseTestCase { @Mock lateinit var taskbarOverlayController: TaskbarOverlayController @Mock lateinit var taskbarEduTooltipController: TaskbarEduTooltipController @Mock lateinit var keyboardQuickSwitchController: KeyboardQuickSwitchController + @Mock lateinit var taskbarPinningController: TaskbarDividerPopupController lateinit var taskbarControllers: TaskbarControllers @@ -91,7 +92,8 @@ abstract class TaskbarBaseTestCase { taskbarSpringOnStashController, taskbarRecentAppsController, taskbarEduTooltipController, - keyboardQuickSwitchController + keyboardQuickSwitchController, + taskbarPinningController, ) } } diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java index 735c5e6fd4..624347131b 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java @@ -29,6 +29,8 @@ import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.tapl.Taskbar; import com.android.launcher3.ui.TaplTestsLauncher3; +import com.android.launcher3.util.LauncherLayoutBuilder; +import com.android.launcher3.util.TestUtil; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch; @@ -49,11 +51,17 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { private static final String CALCULATOR_APP_PACKAGE = resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR); + private AutoCloseable mLauncherLayout; + @Override public void setUp() throws Exception { Assume.assumeTrue(mLauncher.isTablet()); super.setUp(); - mLauncher.useTestWorkspaceLayoutOnReload(); + + LauncherLayoutBuilder layoutBuilder = new LauncherLayoutBuilder().atHotseat(0).putApp( + "com.google.android.apps.nexuslauncher.tests", + "com.android.launcher3.testcomponent.BaseTestingActivity"); + mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, layoutBuilder); TaplTestsLauncher3.initialize(this); startAppFast(CALCULATOR_APP_PACKAGE); @@ -62,9 +70,11 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @After - public void tearDown() { - mLauncher.useDefaultWorkspaceLayoutOnReload(); + public void tearDown() throws Exception { mLauncher.enableBlockTimeout(false); + if (mLauncherLayout != null) { + mLauncherLayout.close(); + } } @Test diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt index 512df8e3d0..acfd54c4d5 100644 --- a/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt +++ b/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt @@ -18,6 +18,7 @@ package com.android.quickstep.util import android.app.ActivityManager +import android.app.PendingIntent import android.content.ComponentName import android.content.Context import android.content.Intent @@ -32,6 +33,8 @@ import com.android.launcher3.statehandlers.DepthController import com.android.launcher3.statemanager.StateManager import com.android.launcher3.util.ComponentKey import com.android.launcher3.util.SplitConfigurationOptions +import com.android.launcher3.util.SplitConfigurationOptions.StagePosition +import com.android.launcher3.util.mock import com.android.launcher3.util.withArgCaptor import com.android.quickstep.RecentsModel import com.android.quickstep.SystemUiProxy @@ -59,6 +62,7 @@ class SplitSelectStateControllerTest { @Mock lateinit var handler: Handler @Mock lateinit var context: Context @Mock lateinit var recentsModel: RecentsModel + @Mock lateinit var pendingIntent: PendingIntent lateinit var splitSelectStateController: SplitSelectStateController @@ -348,6 +352,14 @@ class SplitSelectStateControllerTest { assertFalse(splitSelectStateController.isSplitSelectActive) } + @Test + fun secondPendingIntentSet() { + val itemInfo = ItemInfo() + splitSelectStateController.setInitialTaskSelect(null, 0, itemInfo, null, 1) + splitSelectStateController.setSecondTask(pendingIntent) + assertTrue(splitSelectStateController.isBothSplitAppsConfirmed) + } + // Generate GroupTask with default userId. private fun generateGroupTask( task1ComponentName: ComponentName, diff --git a/res/color/app_title_text_dark.xml b/res/color-night-v31/widget_picker_primary_surface_color_dark.xml similarity index 84% rename from res/color/app_title_text_dark.xml rename to res/color-night-v31/widget_picker_primary_surface_color_dark.xml index 220d10fc8f..13ceaa09e7 100644 --- a/res/color/app_title_text_dark.xml +++ b/res/color-night-v31/widget_picker_primary_surface_color_dark.xml @@ -13,7 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - + + diff --git a/res/color-night-v31/widget_picker_secondary_surface_color_dark.xml b/res/color-night-v31/widget_picker_secondary_surface_color_dark.xml new file mode 100644 index 0000000000..89e9f81b99 --- /dev/null +++ b/res/color-night-v31/widget_picker_secondary_surface_color_dark.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-night-v31/widget_picker_tab_background_unselected_dark.xml b/res/color-night-v31/widget_picker_tab_background_unselected_dark.xml new file mode 100644 index 0000000000..ddd7b0a683 --- /dev/null +++ b/res/color-night-v31/widget_picker_tab_background_unselected_dark.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-v31/widget_picker_primary_surface_color_light.xml b/res/color-v31/widget_picker_primary_surface_color_light.xml new file mode 100644 index 0000000000..02dffdddf7 --- /dev/null +++ b/res/color-v31/widget_picker_primary_surface_color_light.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color-v31/widget_picker_secondary_surface_color_light.xml b/res/color-v31/widget_picker_secondary_surface_color_light.xml new file mode 100644 index 0000000000..cd052681e9 --- /dev/null +++ b/res/color-v31/widget_picker_secondary_surface_color_light.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/res/color/widget_picker_tab_text.xml b/res/color/widget_picker_tab_text.xml new file mode 100644 index 0000000000..0e0fc38316 --- /dev/null +++ b/res/color/widget_picker_tab_text.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/res/color/widgets_picker_scrim.xml b/res/color/widgets_picker_scrim.xml index 5d5130086a..1cf97f61f7 100644 --- a/res/color/widgets_picker_scrim.xml +++ b/res/color/widgets_picker_scrim.xml @@ -18,5 +18,5 @@ */ --> - + diff --git a/res/drawable/bg_widgets_content.xml b/res/drawable/bg_widgets_content.xml index b0b699ba22..1528a9787a 100644 --- a/res/drawable/bg_widgets_content.xml +++ b/res/drawable/bg_widgets_content.xml @@ -24,7 +24,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/res/drawable/bg_widgets_full_sheet.xml b/res/drawable/bg_widgets_full_sheet.xml index dfcd354ce7..66a1d40507 100644 --- a/res/drawable/bg_widgets_full_sheet.xml +++ b/res/drawable/bg_widgets_full_sheet.xml @@ -16,7 +16,7 @@ - + diff --git a/res/drawable/bg_widgets_header_states.xml b/res/drawable/bg_widgets_header_states.xml index f45a7ababf..d03778d0c6 100644 --- a/res/drawable/bg_widgets_header_states.xml +++ b/res/drawable/bg_widgets_header_states.xml @@ -24,7 +24,7 @@ - + - + - + - + - + - + - + diff --git a/res/drawable/bg_widgets_header_two_pane.xml b/res/drawable/bg_widgets_header_two_pane.xml index e1408cc235..ca3feef1f0 100644 --- a/res/drawable/bg_widgets_header_two_pane.xml +++ b/res/drawable/bg_widgets_header_two_pane.xml @@ -20,7 +20,7 @@ android:paddingTop="@dimen/widget_list_header_view_vertical_padding" android:paddingBottom="@dimen/widget_list_header_view_vertical_padding" > - + android:drawable="@drawable/bg_widgets_header_states_two_pane" /> + diff --git a/res/drawable/bg_widgets_searchbox.xml b/res/drawable/bg_widgets_searchbox.xml index dc6d868bd7..b09f0cd1b6 100644 --- a/res/drawable/bg_widgets_searchbox.xml +++ b/res/drawable/bg_widgets_searchbox.xml @@ -14,6 +14,6 @@ limitations under the License. --> - + \ No newline at end of file diff --git a/res/drawable/bottom_rounded_popup_ripple.xml b/res/drawable/bottom_rounded_popup_ripple.xml new file mode 100644 index 0000000000..739833a47c --- /dev/null +++ b/res/drawable/bottom_rounded_popup_ripple.xml @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/drop_target_frame.xml b/res/drawable/drop_target_frame.xml index 9f04103510..0a73b3f05a 100644 --- a/res/drawable/drop_target_frame.xml +++ b/res/drawable/drop_target_frame.xml @@ -17,6 +17,6 @@ - + \ No newline at end of file diff --git a/res/drawable/drop_target_frame_hover.xml b/res/drawable/drop_target_frame_hover.xml index ddf3a4d799..6acffd1542 100644 --- a/res/drawable/drop_target_frame_hover.xml +++ b/res/drawable/drop_target_frame_hover.xml @@ -17,5 +17,5 @@ - + \ No newline at end of file diff --git a/res/drawable/ic_allapps_search.xml b/res/drawable/ic_allapps_search.xml index dbed824358..0c3ab78575 100644 --- a/res/drawable/ic_allapps_search.xml +++ b/res/drawable/ic_allapps_search.xml @@ -20,6 +20,6 @@ android:viewportWidth="24.0" android:autoMirrored="true"> diff --git a/res/drawable/ic_note_taking_widget_category.xml b/res/drawable/ic_note_taking_widget_category.xml new file mode 100644 index 0000000000..2b5915736f --- /dev/null +++ b/res/drawable/ic_note_taking_widget_category.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_touch.xml b/res/drawable/ic_touch.xml new file mode 100644 index 0000000000..ea0e05c547 --- /dev/null +++ b/res/drawable/ic_touch.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/res/drawable/ic_visibility.xml b/res/drawable/ic_visibility.xml new file mode 100644 index 0000000000..864de2ec18 --- /dev/null +++ b/res/drawable/ic_visibility.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/res/drawable/taskbar_divider_bg.xml b/res/drawable/taskbar_divider_bg.xml new file mode 100644 index 0000000000..a8c2ae7032 --- /dev/null +++ b/res/drawable/taskbar_divider_bg.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/res/drawable/top_rounded_popup_ripple.xml b/res/drawable/top_rounded_popup_ripple.xml new file mode 100644 index 0000000000..7468480192 --- /dev/null +++ b/res/drawable/top_rounded_popup_ripple.xml @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/widget_picker_collapse_handle.xml b/res/drawable/widget_picker_collapse_handle.xml new file mode 100644 index 0000000000..f79663d00e --- /dev/null +++ b/res/drawable/widget_picker_collapse_handle.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/res/drawable/widget_picker_tabs_background.xml b/res/drawable/widget_picker_tabs_background.xml new file mode 100644 index 0000000000..a874dd8b90 --- /dev/null +++ b/res/drawable/widget_picker_tabs_background.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/widget_suggestions.xml b/res/drawable/widget_suggestions.xml index b090a68a43..61e42434ba 100644 --- a/res/drawable/widget_suggestions.xml +++ b/res/drawable/widget_suggestions.xml @@ -18,7 +18,7 @@ Copyright (C) 2023 The Android Open Source Project android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="@color/widget_picker_background_selected" + android:tint="?attr/widgetPickerSuggestionsIconColor" android:gravity="center" > - + - + \ No newline at end of file diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml index e31bf7affe..9ec346a261 100644 --- a/res/layout/widgets_full_sheet.xml +++ b/res/layout/widgets_full_sheet.xml @@ -34,7 +34,7 @@ android:layout_height="@dimen/bottom_sheet_handle_height" android:layout_marginTop="@dimen/bottom_sheet_handle_margin" android:layout_centerHorizontal="true" - android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/> + android:background="@drawable/widget_picker_collapse_handle"/> @@ -89,7 +89,7 @@ android:gravity="center_horizontal" android:orientation="horizontal" android:paddingVertical="8dp" - android:background="?android:attr/colorBackground" + android:background="?attr/widgetPickerPrimarySurfaceColor" style="@style/TextHeadline" launcher:layout_sticky="true"> @@ -100,9 +100,9 @@ android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding" android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding" android:layout_weight="1" - android:background="@drawable/all_apps_tabs_background" + android:background="@drawable/widget_picker_tabs_background" android:text="@string/widgets_full_sheet_personal_tab" - android:textColor="@color/all_apps_tab_text" + android:textColor="@color/widget_picker_tab_text" android:textSize="14sp" style="?android:attr/borderlessButtonStyle" /> @@ -113,9 +113,9 @@ android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding" android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding" android:layout_weight="1" - android:background="@drawable/all_apps_tabs_background" + android:background="@drawable/widget_picker_tabs_background" android:text="@string/widgets_full_sheet_work_tab" - android:textColor="@color/all_apps_tab_text" + android:textColor="@color/widget_picker_tab_text" android:textSize="14sp" style="?android:attr/borderlessButtonStyle" /> diff --git a/res/layout/widgets_full_sheet_recyclerview.xml b/res/layout/widgets_full_sheet_recyclerview.xml index 887f00cbd0..25bbad41fa 100644 --- a/res/layout/widgets_full_sheet_recyclerview.xml +++ b/res/layout/widgets_full_sheet_recyclerview.xml @@ -41,7 +41,7 @@ android:gravity="center_horizontal" android:textSize="24sp" android:layout_marginTop="24dp" - android:textColor="?android:attr/textColorSecondary" + android:textColor="?attr/widgetPickerTitleColor" android:text="@string/widget_button_text"/> diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml index 6d44865ef0..a615c5e025 100644 --- a/res/layout/widgets_search_bar.xml +++ b/res/layout/widgets_search_bar.xml @@ -25,7 +25,7 @@ android:imeOptions="actionSearch" android:importantForAutofill="no" android:textColor="?android:attr/textColorPrimary" - android:textColorHint="?android:attr/textColorSecondary"/> + android:textColorHint="?attr/widgetPickerSearchTextColor"/> + android:background="@drawable/widget_picker_collapse_handle"/> @@ -87,7 +87,7 @@ android:orientation="horizontal" android:paddingVertical="8dp" android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane" - android:background="?android:attr/colorBackground" + android:background="?attr/widgetPickerPrimarySurfaceColor" style="@style/TextHeadline" launcher:layout_sticky="true"> @@ -98,9 +98,9 @@ android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding" android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding" android:layout_weight="1" - android:background="@drawable/all_apps_tabs_background" + android:background="@drawable/widget_picker_tabs_background" android:text="@string/widgets_full_sheet_personal_tab" - android:textColor="@color/all_apps_tab_text" + android:textColor="@color/widget_picker_tab_text" android:textSize="14sp" style="?android:attr/borderlessButtonStyle" /> @@ -111,9 +111,9 @@ android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding" android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding" android:layout_weight="1" - android:background="@drawable/all_apps_tabs_background" + android:background="@drawable/widget_picker_tabs_background" android:text="@string/widgets_full_sheet_work_tab" - android:textColor="@color/all_apps_tab_text" + android:textColor="@color/widget_picker_tab_text" android:textSize="14sp" style="?android:attr/borderlessButtonStyle" /> diff --git a/res/layout/widgets_two_pane_sheet_recyclerview.xml b/res/layout/widgets_two_pane_sheet_recyclerview.xml index 8f2a25e409..f8d72e89d4 100644 --- a/res/layout/widgets_two_pane_sheet_recyclerview.xml +++ b/res/layout/widgets_two_pane_sheet_recyclerview.xml @@ -43,7 +43,7 @@ android:id="@+id/search_bar_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?android:attr/colorBackground" + android:background="?attr/widgetPickerPrimarySurfaceColor" android:clipToPadding="false" android:elevation="0.1dp" android:paddingBottom="8dp" @@ -61,7 +61,7 @@ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane" android:paddingBottom="16dp" android:orientation="horizontal" - android:background="?android:attr/colorBackground" + android:background="?attr/widgetPickerPrimarySurfaceColor" launcher:layout_sticky="true"> diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index faee52632e..377025a49c 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -81,7 +81,6 @@ "Laat die program toe om die instellings en kortpaaie op tuisskerm te lees." "skryf tuis-instellings en -kortpaaie" "Laat die program toe om die instellings en kortpaaie op tuisskerm te verander." - "%1$s word nie toegelaat om foonoproepe te maak nie" "Kan nie legstuk laai nie" "Legstukinstellings" "Tik om opstelling te voltooi" @@ -101,6 +100,7 @@ "Vouer: %1$s, %2$d of meer items" "Muurpapiere" "Muurpapier en styl" + "Wysig tuisskerm" "Tuis-instellings" "Gedeaktiveer deur jou administrateur" "Laat toe dat tuisskerm gedraai word" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index b67a98ea75..3d0b3d59dc 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -27,7 +27,7 @@ "ምግብሮች በደህንነቱ የተጠበቀ ሁኔታ ተሰናክለዋል" "አቋራጭ አይገኝም" "መነሻ" - "የተከፈለ ማያ ገጽ" + "የተከፈለ ማያ ገፅ" "የመተግበሪያ መረጃ ለ%1$s" "የመተግበሪያ ጥምረትን ያስቀምጡ" "ምግብርን ለማንቀሳቀስ ይንኩ እና ይያዙ።" @@ -35,9 +35,9 @@ "%1$d × %2$d" "%1$d ስፋት በ%2$d ከፍታ" "የ%1$s ምግብር" - "በመነሻ ማያ ገጽ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት" - "ወደ መነሻ ማያ ገጽ አክል" - "%1$s ምግብር ወደ መነሻ ማያ ገጽ ታክሏል" + "በመነሻ ማያ ገፅ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት" + "ወደ መነሻ ማያ ገፅ አክል" + "%1$s ምግብር ወደ መነሻ ማያ ገፅ ታክሏል" "የአስተያየት ጥቆማዎች" "{count,plural, =1{# ምግብር}one{# ምግብሮች}other{# ምግብሮች}}" "{count,plural, =1{# አቋራጭ}one{# አቋራጭ}other{# አቋራጮች}}" @@ -63,7 +63,7 @@ "ማሳወቂያዎች" "አቋራጭን ለማንቀሳቀስ ይንኩ እና ይያዙ" "አቋራጭን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።" - "በዚህ የመነሻ ማያ ገጽ ላይ ምንም ክፍል የለም" + "በዚህ የመነሻ ማያ ገፅ ላይ ምንም ክፍል የለም" "በተወዳጆች መሣቢያ ውስጥ ተጨማሪ ቦታ የለም" "የመተግበሪያዎች ዝርዝር" "የፍለጋ ውጤቶች" @@ -81,7 +81,6 @@ "ቅንብሮችን እና አቋራጮችን በመነሻ ለማንበብ ለትግበራ ይፈቅዳል።" "መነሻ ቅንብሮች እና አቋራጮች ጻፍ" "ቅንብሮችን እና አቋራጮችን በመነሻ ለመለወጥ ለመተግበሪያ ይፈቅዳል።" - "%1$s የስልክ ጥሪዎችን ለማድረግ አልተፈቀደለትም" "ምግብርን መጫን አልተቻለም" "የምግብር ቅንብሮች" "ማዋቀርን ለመጨረስ መታ ያድርጉ" @@ -89,9 +88,9 @@ "ስም ያርትዑ" "%1$s ተሰናክሏል" "{count,plural, =1{{app_name}፣ # ማሳወቂያ አለው}one{{app_name}፣ # ማሳወቂያዎች አሉት}other{{app_name}፣ # ማሳወቂያዎች አሉት}}" - "ገጽ %1$d ከ%2$d" - "መነሻ ማያ ገጽ %1$d ከ%2$d" - "አዲስ የመነሻ ማያ ገጽ" + "ገፅ %1$d ከ%2$d" + "መነሻ ማያ ገፅ %1$d ከ%2$d" + "አዲስ የመነሻ ማያ ገፅ" "አቃፊ ተከፍቷል፣ %1$d%2$d" "አቃፊን ለመዝጋት መታ ያድርጉ" "ዳግም የተሰጠውን ስም ለማስቀመጥ መታ ያድርጉ" @@ -101,9 +100,10 @@ "አቃፊ፦ %1$s%2$d ወይም ተጨማሪ ንጥሎች" "የግድግዳ ወረቀቶች" "ልጣፍ እና ቅጥ" + "መነሻ ማያ ገጽን አርትዕ" "የመነሻ ቅንብሮች" "በእርስዎ አስተዳዳሪ የተሰናከለ" - "የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ" + "የመነሻ ማያ ገፅ ማሽከርከርን ይፍቀዱ" "ስልኩ ሲዞር" "የማሳወቂያ ነጥቦች" "አብራ" @@ -129,9 +129,9 @@ "አስወግድ" "የመግብሮች ዝርዝር" "የመግብሮች ዝርዝር ተዘግቷል" - "ወደ መነሻ ማያ ገጽ አክል" + "ወደ መነሻ ማያ ገፅ አክል" "ንጥልን ወደዚህ ውሰድ" - "ወደ መነሻ ማያ ገጽ ንጥል ታክሏል" + "ወደ መነሻ ማያ ገፅ ንጥል ታክሏል" "ንጥል ነገር ተንቀሳቅሷል" "ቀልብስ" "ንጥልን አንቀሳቅስ" @@ -144,7 +144,7 @@ "ንጥል ወደ አቃፊ ታክሏል" "አቃፊ ፍጠር ከዚህ ጋር፦ %1$s" "አቃፊ ተፈጥሮዋል" - "ወደ መነሻ ማያ ገጽ አንቀሳቅስ" + "ወደ መነሻ ማያ ገፅ አንቀሳቅስ" "መጠን ቀይር" "ስፋት ጨምር" "ቁመት ጨምር" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index a236cd7ca8..cca2e970e0 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -81,7 +81,6 @@ "يسمح هذا الإذن للتطبيق بالاطلاع على الإعدادات والاختصارات على الشاشة الرئيسية." "تعديل الإعدادات والاختصارات على الشاشة الرئيسية" "يسمح هذا الإذن للتطبيق بتغيير الإعدادات والاختصارات على الشاشة الرئيسية." - "%1$s غير مسموح به لإجراء مكالمات هاتفية" "يتعذّر تحميل الأداة." "إعدادات الأداة" "انقر لإكمال الإعداد." @@ -101,12 +100,13 @@ "المجلد: %1$s، %2$d عنصر أو أكثر" "الخلفيات" "الخلفية والأسلوب" + "تعديل الشاشة الرئيسية" "إعدادات الشاشة الرئيسية" "أوقف المشرف هذه الميزة" "السماح بتدوير الشاشة الرئيسية" "عند تدوير الهاتف" "نقاط الإشعارات" - "مفعّلة" + "الإعداد مفعّل" "غير مفعّل" "يلزم تمكين الوصول إلى الإشعارات" "لعرض نقاط الإشعارات، يجب تفعيل إشعارات التطبيق في %1$s" @@ -159,13 +159,13 @@ "شخصية" "للعمل" "الملف الشخصي للعمل" - "تحمل تطبيقات العمل شارة وتكون مرئية لمشرف تكنولوجيا المعلومات." + "تحمل تطبيقات العمل مميّزة بشارة ومرئية لمشرف تكنولوجيا المعلومات." "حسنًا" "تطبيقات العمل متوقفة مؤقتًا" "لن تتلقّى إشعارات من تطبيقات العمل." "لا يمكن لتطبيقات العمل إرسال إشعارات إليك أو استخدام بطاريتك أو الوصول إلى موقعك الجغرافي." "لن تتلقّى مكالمات هاتفية أو رسائل نصية أو إشعارات من تطبيقات العمل." - "تحمل تطبيقات العمل شارة وتكون مرئية لمشرف تكنولوجيا المعلومات." + "تكون تطبيقات العمل مميّزة بشارة ومرئية لمشرف تكنولوجيا المعلومات." "حسنًا" "إيقاف تطبيقات العمل مؤقتًا" "إلغاء الإيقاف المؤقت" diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index e7861264b8..583a5c4bbd 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -55,8 +55,8 @@ "ৱিজেটৰ ছেটিং সলনি কৰিবলৈ টিপক" "বুজি পালোঁ" "ৱিজেটৰ ছেটিং সলনি কৰক" - "এপসমূহ সন্ধান কৰক" - "এপসমূহ ল’ড কৰি থকা হৈছে…" + "এপ্‌সমূহ সন্ধান কৰক" + "এপ্‌সমূহ ল’ড কৰি থকা হৈছে…" "\"%1$s\"ৰ সৈতে মিলা কোনো এপ্ বিচাৰি পোৱা নগ\'ল" "এপ্" "আটাইবোৰ এপ্" @@ -81,7 +81,6 @@ "এপ্‌টোক গৃহ স্ক্ৰীনত ছেটিং আৰু শ্বৰ্টকাটসমূহ পঢ়াৰ অনুমতি দিয়ে।" "গৃহ স্ক্ৰীনত ছেটিং আৰু শ্বৰ্টকাটসমূহ লিখা" "এপ্‌টোক গৃহ স্ক্ৰীনত ছেটিং আৰু শ্বৰ্টকাটসমূহ সলনি কৰাৰ অনুমতি দিয়ে।" - "%1$sক ফ\'ন কলবোৰ কৰাৰ অনুমতি দিয়া হোৱা নাই" "ৱিজেট ল’ড কৰিব নোৱাৰি" "ৱিজেটৰ ছেটিং" "ছেটআপ সমাপ্ত কৰিবলৈ টিপক" @@ -101,6 +100,7 @@ "ফ’ল্ডাৰ: %1$s, %2$d টা অথবা তাতকৈ অধিক বস্তু" "ৱালপেপাৰসমূহ" "ৱালপেপাৰ আৰু শৈলী" + "গৃহ স্ক্ৰীন সম্পাদনা কৰক" "গৃহ ছেটিং" "আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে" "গৃহ স্ক্ৰীন ঘূৰোৱাৰ অনুমতি দিয়ক" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 74c6048342..c5ceac60fa 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -81,7 +81,6 @@ "Tətbiqə Əsas səhifədə ayarları və qısayolları oxumağa icazə verir." "Əsas səhifə ayarlarını və qısayollarını yazmaq" "Tətbiqə Əsas səhifədə ayarları və qısayolları dəyişməyə icazə verir." - "%1$s tətbiqinə telefon zəngləri etmək üçün icazə verilmir" "Vidceti yükləmək olmur" "Vidcet ayarları" "Ayarlamanı tamamlamaq üçün toxunun" @@ -101,6 +100,7 @@ "Qovluq: %1$s, %2$d və ya daha çox element" "Divar kağızları" "Divar kağızı və üslub" + "Əsas ekranı redaktə edin" "Home ayarları" "Admininiz tərəfindən deaktiv edilib" "Əsas ekran çevrilsin" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index a8353c431d..4b7392b7b9 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -81,7 +81,6 @@ "Dozvoljava aplikaciji da čita podešavanja i prečice na početnom ekranu." "upisivanje podešavanja i prečica na početnom ekranu" "Dozvoljava aplikaciji da menja podešavanja i prečice na početnom ekranu." - "%1$s nema dozvolu za upućivanje telefonskih poziva" "Učitavanje vidžeta nije uspelo" "Podešavanja vidžeta" "Dodirnite da biste dovršili podešavanje" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d ili više stavki" "Pozadine" "Pozadina i stil" + "Izmeni početni ekran" "Podešavanja početnog ekrana" "Administrator je onemogućio" "Dozvoli rotaciju početnog ekrana" @@ -156,8 +156,8 @@ "Odbaci" "Zatvori" "Obaveštenje je odbačeno" - "Lične" - "Poslovne" + "Lično" + "Posao" "Poslovni profil" "Poslovne aplikacije su označene značkom i IT administrator može da ih vidi" "Važi" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index d74dbd82c2..2231f88642 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -81,7 +81,6 @@ "Дазваляе праграме счытваць налады і ярлыкі на галоўным экране." "запісваць налады і ярлыкі на галоўны экран" "Дазваляе праграме змяняць налады і ярлыкі на галоўным экране." - "%1$s не мае дазволу на здзяйсненне тэлефонных званкоў" "Не ўдаецца загрузіць віджэт" "Налады віджэта" "Націсніце, каб завяршыць наладжванне" @@ -101,6 +100,7 @@ "Папка: %1$s, элементы: %2$d ці больш" "Шпалеры" "Шпалеры і стыль" + "Змяніць Галоўны экран" "Налады галоўнага экрана" "Адключаная адміністратарам" "Дазволіць паварот галоўнага экрана" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 7d8096b763..992abeb214 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -81,7 +81,6 @@ "Разрешава на приложението да чете настройките и преките пътища на началния екран." "запис на настройките и преките пътища на началния екран" "Разрешава на приложението да променя настройките и преките пътища на началния екран." - "%1$s няма разрешение да извършва телефонни обаждания" "Приспособлението не може да се зареди" "Настройки за приспособленията" "Докоснете, за да завършите настройването" @@ -101,6 +100,7 @@ "Папка: „%1$s“ – %2$d или повече елементи" "Тапети" "Тапет и стил" + "Редактиране на началния екран" "Настройки за началния екран" "Деактивирано от администратора ви" "Разрешаване на завъртането на началния екран" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index bd76e6c730..a2ba82b4d0 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -81,7 +81,6 @@ "অ্যাপকে হোম স্ক্রিনে সেটিংস ও শর্টকাট পড়ার অনুমতি দেয়।" "হোম স্ক্রিনে সেটিংস ও শর্টকাট লিখুন" "অ্যাপকে হোম স্ক্রিনে সেটিংস ও শর্টকাট পরিবর্তন করার অনুমতি দেয়।" - "ফোন কলগুলি করার জন্য %1$s এর অনুমতি নেই" "উইজেট লোড করা যাচ্ছে না" "উইজেট সেটিংস" "সেটআপ সম্পূর্ণ করতে ট্যাপ করুন" @@ -101,6 +100,7 @@ "ফোল্ডার: %1$s, %2$dটি বা তার বেশি আইটেম" "ওয়ালপেপারগুলি" "ওয়ালপেপার এবং স্টাইল" + "হোম স্ক্রিন এডিট করুন" "হোম সেটিংস" "আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে" "হোম স্ক্রিন রোটেট করার অনুমতি দিন" @@ -159,13 +159,13 @@ "ব্যক্তিগত" "অফিস" "অফিসের প্রোফাইল" - "অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেটি দেখতে পাবেন" + "অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেগুলি দেখতে পাবেন" "বুঝেছি" "অফিস অ্যাপ বন্ধ করা আছে" "আপনার অফিসের অ্যাপ থেকে আপনি কোনও বিজ্ঞপ্তি পাবেন না" "অফিসের অ্যাপ আপনাকে নোটিফিকেশন পাঠাতে পারবে না। এছাড়া, ব্যাটারি ব্যবহার করতে বা লোকেশন অ্যাক্সেস করতে পারবে না" "আপনি কোনও ফোন কল, টেক্সট মেসেজ বা অফিসের অ্যাপ থেকে বিজ্ঞপ্তি পাবেন না" - "অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেটি দেখতে পাবেন" + "অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেগুলি দেখতে পাবেন" "বুঝেছি" "অফিসের অ্যাপ পজ করুন" "আনপজ করুন" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 1dc1863493..20fc18a6cc 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -81,7 +81,6 @@ "Dopušta aplikaciji čitanje postavki i prečica na početnom ekranu." "zapisuje postavke na početnom ekranu i prečice" "Dopušta aplikaciji promjenu postavki i prečica na početnom ekranu." - "%1$s nema odobrenje da uspostavlja telefonske pozive" "Nije moguće učitati vidžet" "Postavke vidžeta" "Dodirnite da završite postavljanje" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d ili više stavki" "Pozadinske slike" "Pozadinska slika i stil" + "Uredi Početni ekran" "Postavke početnog ekrana" "Onemogućio vaš administrator" "Dozvoli rotiranje početnog ekrana" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index fc462fdafa..885a55e943 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -81,7 +81,6 @@ "Permet que l\'aplicació llegeixi la configuració i les dreceres de la pantalla d\'inici." "escriure la configuració i les dreceres de la pantalla d\'inici" "Permet que l\'aplicació canviï la configuració i les dreceres de la pantalla d\'inici." - "%1$s no té permís per fer trucades telefòniques" "No es pot carregar el widget" "Configuració del widget" "Toca per finalitzar la configuració" @@ -101,6 +100,7 @@ "Carpeta: %1$s, %2$d o més elements" "Fons de pantalla" "Estil i fons de pantalla" + "Edita la pantalla d\'inici" "Config. pantalla d\'inici" "Desactivada per l\'administrador" "Permet la rotació de la pantalla d\'inici" @@ -159,13 +159,13 @@ "Personal" "Treball" "Perfil de treball" - "Les aplicacions de treball tenen una insígnia i són visibles per al teu administrador de TI" + "Les aplicacions de treball tenen una insígnia i el teu administrador de TI les pot veure" "Entesos" "Les aplicacions de treball estan en pausa" "No rebràs cap notificació de les aplicacions de treball" "Les aplicacions de treball no poden enviar-te notificacions, consumir bateria ni accedir a la teva ubicació" "No rebràs trucades, missatges de text ni notificacions de les aplicacions de treball" - "Les aplicacions de treball tenen una insígnia i són visibles per al teu administrador de TI" + "Les aplicacions de treball tenen una insígnia i el teu administrador de TI les pot veure" "Entesos" "Posa en pausa les aplicacions de treball" "Reactiva" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 1d05d8826b..25f7f0f0b8 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -81,7 +81,6 @@ "Umožňuje aplikaci číst nastavení a zkratky na ploše." "zápis nastavení a zkratek plochy" "Umožňuje aplikaci změnit nastavení a zkratky na ploše." - "Aplikace %1$s nemá oprávnění telefonovat" "Widget se nepodařilo načíst" "Nastavení widgetů" "Klepnutím dokončíte konfiguraci" @@ -101,6 +100,7 @@ "Složka: %1$s, počet položek: %2$d nebo více" "Tapety" "Tapeta a styl" + "Upravit plochu" "Nastavení plochy" "Zakázáno administrátorem" "Povolit otáčení plochy" @@ -171,6 +171,6 @@ "Zrušit pozastavení" "Filtr" "Prohledávání telefonu" - "Vyhledávat na tabletu" + "Vyhledávání na tabletu" "Selhalo: %1$s" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 36e3e7d043..40fb99e994 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -81,7 +81,6 @@ "Tillader, at appen læser indstillingerne og genvejene på startskærmen." "skriv indstillinger og genveje for startskærm" "Tillader, at appen ændrer indstillingerne og genvejene på startskærmen." - "%1$s har ikke tilladelse til at foretage telefonopkald" "Widgetten kan ikke indlæses" "Widget-indstillinger" "Tryk for at fuldføre konfigurationen" @@ -101,6 +100,7 @@ "Mappe: %1$s, %2$d eller flere elementer" "Baggrunde" "Baggrund og stil" + "Rediger startskærm" "Indst. for startskærm" "Deaktiveret af din administrator" "Tillad rotation af startskærmen" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 46367e657d..fd0de654b5 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -27,7 +27,7 @@ "Widgets im abgesicherten Modus deaktiviert" "Verknüpfung nicht verfügbar" "Startbildschirm" - "Geteilter Bildschirm" + "Splitscreen" "App-Info für %1$s" "App-Paar speichern" "Zum Verschieben des Widgets berühren und halten" @@ -81,7 +81,6 @@ "Ermöglicht der App, die Einstellungen und Verknüpfungen auf dem Startbildschirm zu lesen." "Einstellungen und Verknüpfungen für den Startbildschirm schreiben" "Ermöglicht der App, die Einstellungen und Verknüpfungen auf dem Startbildschirm zu ändern." - "%1$s darf keine Telefonanrufe tätigen." "Widget kann nicht geladen werden" "Widget-Einstellungen" "Tippen, um Einrichtung abzuschließen" @@ -101,6 +100,7 @@ "Ordner: %1$s, %2$d oder mehr Elemente" "Hintergründe" "Hintergrund & Stil" + "Startbildschirm bearbeiten" "Einstellungen" "Von deinem Administrator deaktiviert" "Drehen des Startbildschirms zulassen" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index d52a8b18dc..a399a4e7f8 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -81,7 +81,6 @@ "Επιτρέπει στην εφαρμογή την ανάγνωση των ρυθμίσεων και των συντομεύσεων στην αρχική οθόνη." "εγγραφή ρυθμίσεων και συντομεύσεων αρχικής οθόνης" "Επιτρέπει στην εφαρμογή την αλλαγή των ρυθμίσεων και των συντομεύσεων στην αρχική οθόνη." - "Η εφαρμογή %1$s δεν επιτρέπεται να πραγματοποιεί τηλεφωνικές κλήσεις" "Δεν είναι δυνατή η φόρτωση του γραφικού στοιχείου" "Ρυθμίσεις γραφικών στοιχείων" "Πατήστε για να ολοκληρώσετε τη ρύθμιση" @@ -101,6 +100,7 @@ "Φάκελος: %1$s, %2$d ή περισσότερα στοιχεία" "Ταπετσαρίες" "Ταπετσαρία και στιλ" + "Επεξεργασία αρχικής οθόνης" "Ρυθμίσεις Αρχ. Οθ." "Απενεργοποιήθηκε από τον διαχειριστή σας" "Να επιτρέπεται η περιστροφή της αρχικής οθόνης" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index a3b25c844e..eea6581f36 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -81,7 +81,6 @@ "Allows the app to read the settings and shortcuts in Home." "write Home settings and shortcuts" "Allows the app to change the settings and shortcuts in Home." - "%1$s is not allowed to make phone calls" "Can\'t load widget" "Widget settings" "Tap to finish setup" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d or more items" "Wallpapers" "Wallpaper and style" + "Edit home screen" "Home settings" "Disabled by your admin" "Allow home screen rotation" diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 72aa73ec17..32efb8cca5 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -30,12 +30,12 @@ "Split screen" "App info for %1$s" "Save app pair" - "Touch & hold to move a widget." - "Double-tap & hold to move a widget or use custom actions." + "Touch and hold to move a widget." + "Double-tap and hold to move a widget or use custom actions." "%1$d × %2$d" "%1$d wide by %2$d high" "%1$s widget" - "Touch & hold the widget to move it around the home screen" + "Touch and hold the widget to move it around the home screen" "Add to home screen" "%1$s widget added to home screen" "Suggestions" @@ -61,8 +61,8 @@ "App" "All apps" "Notifications" - "Touch & hold to move a shortcut." - "Double-tap & hold to move a shortcut or use custom actions." + "Touch and hold to move a shortcut." + "Double-tap and hold to move a shortcut or use custom actions." "No room on this home screen" "No more room in the Favorites tray" "Apps list" @@ -81,7 +81,6 @@ "Allows the app to read the settings and shortcuts in home." "write home settings and shortcuts" "Allows the app to change the settings and shortcuts in home." - "%1$s is not allowed to make phone calls" "Can\'t load widget" "Widget settings" "Tap to finish setup" @@ -100,7 +99,8 @@ "Folder: %1$s, %2$d items" "Folder: %1$s, %2$d or more items" "Wallpapers" - "Wallpaper & style" + "Wallpaper and style" + "Edit Home Screen" "Home settings" "Disabled by your admin" "Allow home screen rotation" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index a3b25c844e..eea6581f36 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -81,7 +81,6 @@ "Allows the app to read the settings and shortcuts in Home." "write Home settings and shortcuts" "Allows the app to change the settings and shortcuts in Home." - "%1$s is not allowed to make phone calls" "Can\'t load widget" "Widget settings" "Tap to finish setup" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d or more items" "Wallpapers" "Wallpaper and style" + "Edit home screen" "Home settings" "Disabled by your admin" "Allow home screen rotation" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index a3b25c844e..eea6581f36 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -81,7 +81,6 @@ "Allows the app to read the settings and shortcuts in Home." "write Home settings and shortcuts" "Allows the app to change the settings and shortcuts in Home." - "%1$s is not allowed to make phone calls" "Can\'t load widget" "Widget settings" "Tap to finish setup" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d or more items" "Wallpapers" "Wallpaper and style" + "Edit home screen" "Home settings" "Disabled by your admin" "Allow home screen rotation" diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 23fd7b4c14..31fea4b7be 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -81,7 +81,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎Allows the app to read the settings and shortcuts in home.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎write home settings and shortcuts‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎Allows the app to change the settings and shortcuts in home.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is not allowed to make phone calls‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎Can\'t load widget‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎Widget settings‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎Tap to finish setup‎‏‎‎‏‎" @@ -101,6 +100,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‎Folder: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎%2$d‎‏‎‎‏‏‏‎ or more items‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎Wallpapers‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎Wallpaper & style‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎Edit Home Screen‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎Home settings‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎Disabled by your admin‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎Allow home screen rotation‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 7d0cd22f70..ee322ea5a8 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -81,7 +81,6 @@ "Permite que la app lea los parámetros de configuración y los accesos directos de la página principal." "escribir parámetros de configuración y accesos directos de la página principal" "Permite que la app cambie los parámetros de configuración y los accesos directos de la página principal." - "%1$s no puede realizar llamadas telefónicas" "No se puede cargar el widget" "Configuración del widget" "Presiona para finalizar la configuración" @@ -101,6 +100,7 @@ "Carpeta: %1$s, %2$d o más elementos" "Fondos de pantalla" "Fondo de pantalla y estilo" + "Editar pantalla principal" "Configuración de pantalla principal" "El administrador inhabilitó esta función" "Permitir la rotación de la pantalla principal" @@ -171,6 +171,6 @@ "Reanudar" "Filtro" "Busca tu teléfono" - "Busca tu tablet" + "Busca en tu tablet" "Error: %1$s" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 5c0c8f34d1..e7b40b4011 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -81,7 +81,6 @@ "Permite que la aplicación lea los ajustes y los accesos directos de la pantalla de inicio." "escribir ajustes y accesos directos de la pantalla de inicio" "Permite que la aplicación cambie los ajustes y los accesos directos de la pantalla de inicio." - "%1$s no puede hacer llamadas" "No se puede cargar el widget" "Ajustes de widget" "Toca para finalizar la configuración" @@ -101,6 +100,7 @@ "Carpeta: %1$s (%2$d o más elementos)" "Fondos de pantalla" "Fondo de pantalla y estilo" + "Editar pantalla de inicio" "Ajustes de la pantalla de inicio" "Inhabilitado por el administrador" "Permitir rotación de la pantalla de inicio" @@ -171,6 +171,6 @@ "Reanudar" "Filtro" "Busca en tu teléfono" - "Busca en tu tablet" + "Buscar en tu tablet" "Se ha producido un error: %1$s" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index c7a273d3ae..f0ff7a8dc6 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -81,7 +81,6 @@ "Võimaldab rakendusel lugeda avakuva seadeid ja otseteid." "avakuva seadete ja otseteede kirjutamine" "Võimaldab rakendusel muuta avakuval seadeid ja otseteid." - "Rakendusel %1$s pole lubatud helistada" "Vidinat ei saa laadida" "Vidina seaded" "Puudutage seadistuse lõpuleviimiseks" @@ -101,6 +100,7 @@ "Kaust: %1$s, %2$d või rohkem üksust" "Taustapildid" "Taustapilt ja stiil" + "Muuda avaekraani" "Avakuva seaded" "Keelas administraator" "Luba avakuva pööramine" @@ -168,7 +168,7 @@ "Töörakendustel on märk ja need on teie IT-administraatorile nähtavad" "Selge" "Peata töörakendused" - "Jätka" + "Lõpeta peatamine" "Filter" "Otsimine telefonist" "Otsimine tahvelarvutist" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 28a323e148..642eb6bd00 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -81,7 +81,6 @@ "Hasierako pantailako ezarpenak eta lasterbideak irakurtzeko baimena ematen die aplikazioei." "idatzi hasierako pantailako ezarpenak eta lasterbideak" "Hasierako pantailako ezarpenak eta lasterbideak aldatzeko baimena ematen die aplikazioei." - "%1$s aplikazioak ez du telefono-deiak egiteko baimenik" "Ezin da kargatu widgeta" "Widgetaren ezarpenak" "Sakatu konfiguratzen amaitzeko" @@ -101,6 +100,7 @@ "%1$s karpeta (%2$d elementu edo gehiago)" "Horma-paperak" "Horma-papera eta estiloa" + "Editatu hasierako pantaila" "Hasierako pantailaren ezarpenak" "Administratzaileak desgaitu du" "Eman hasierako pantaila biratzeko baimena" @@ -161,7 +161,7 @@ "Laneko profila" "Laneko aplikazioek bereizgarriak dituzte, eta IKT saileko administratzaileak ikus ditzake" "Ados" - "Pausatu egin dira laneko aplikazioak" + "Pausatuta daude laneko aplikazioak" "Ez duzu jasoko laneko aplikazioen jakinarazpenik" "Laneko aplikazioek ezin dute jakinarazpenik bidali, bateria erabili edo kokapena atzitu" "Ez duzu jasoko laneko aplikazioen telefono-deirik, testu-mezurik edo jakinarazpenik" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index bc9f9a669d..6708519c14 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -81,7 +81,6 @@ "به برنامه اجازه می‌دهد تنظیمات و میان‌برهای صفحه اصلی را بخواند." "نوشتن تنظیمات و میان‌برهای صفحه اصلی" "به برنامه اجازه می‌دهد تنظیمات و میان‌برهای صفحه اصلی را تغییر دهد." - "%1$s مجاز نیست تماس تلفنی برقرار کند" "ابزارک را نمی‌توان بار کرد" "تنظیمات ابزارک" "برای تکمیل راه‌اندازی ضربه بزنید" @@ -101,6 +100,7 @@ "پوشه: %1$s، %2$d مورد یا بیشتر" "کاغذدیواری‌ها" "کاغذدیواری و سبک" + "ویرایش «صفحه اصلی»" "تنظیمات صفحه اصلی" "توسط سرپرست سیستم غیرفعال شده است" "مجاز کردن چرخش صفحه اصلی" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 1097417304..adf4cb8df8 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -81,7 +81,6 @@ "Antaa sovelluksen lukea aloitusnäytön asetuksia ja pikakuvakkeita" "muokata aloitusnäytön asetuksia ja pikakuvakkeita" "Antaa sovelluksen muuttaa aloitusnäytön asetuksia ja pikakuvakkeita" - "%1$s ei saa soittaa puheluita." "Widgetiä ei voi ladata" "Widgetin asetukset" "Viimeistele asennus napauttamalla" @@ -101,6 +100,7 @@ "Kansio: %1$s, ainakin %2$d kohdetta" "Taustakuvat" "Taustakuva ja tyyli" + "Muokkaa aloitusnäyttöä" "Aloitusnäyttö" "Järjestelmänvalvoja on poistanut toiminnon käytöstä." "Salli aloitusnäytön kiertäminen" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index a49f0e32da..213df55f9e 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -81,7 +81,6 @@ "Permet à l\'application de lire les paramètres et les raccourcis de l\'écran d\'accueil." "modifier les paramètres et les raccourcis de la page d\'accueil" "Permet à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil." - "L\'application %1$s n\'est pas autorisée à faire des appels téléphoniques" "Impossible de charger le widget" "Paramètres du widget" "Touchez pour terminer la configuration" @@ -101,6 +100,7 @@ "Dossier : %1$s, %2$d éléments ou plus" "Fonds d\'écran" "Fond d\'écran et style" + "Modifier l\'écran d\'accueil" "Paramètres d\'accueil" "Cette fonction est désactivée par votre administrateur" "Autoriser la rotation de l\'écran d\'accueil" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 7b48cde2d0..3a95a5740f 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -81,7 +81,6 @@ "Permet à l\'application de lire les paramètres et les raccourcis de l\'écran d\'accueil." "Modifier les paramètres de la page d\'accueil et les raccourcis" "Permet à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil." - "L\'application %1$s n\'est pas autorisée à passer des appels téléphoniques." "Impossible de charger le widget" "Paramètres du widget" "Appuyez pour terminer la configuration" @@ -101,12 +100,13 @@ "Dossier : %1$s, %2$d éléments ou plus" "Fonds d\'écran" "Fond d\'écran et style" + "Modifier l\'écran d\'accueil" "Paramètres de l\'accueil" "Désactivé par votre administrateur" "Autoriser la rotation de l\'écran d\'accueil" "Lorsque vous faites pivoter le téléphone" "Pastilles de notification" - "Activées" + "Activé" "Désactivées" "Accès aux notifications requis" "Pour afficher les pastilles de notification, activez les notifications de l\'application %1$s" @@ -161,7 +161,7 @@ "Profil professionnel" "Les applis professionnelles sont identifiées par un badge et votre administrateur informatique peut les voir" "OK" - "Applications professionnelles en veille" + "Applis professionnelles en pause" "Vous ne recevrez pas de notifications de vos applications professionnelles" "Vos applis professionnelles ne peuvent pas vous envoyer de notifications, utiliser votre batterie ni accéder à votre position" "Vous ne recevrez pas d\'appels téléphoniques, de messages ni de notifications de vos applications professionnelles" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 7d675748ae..e8863d9df8 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -81,7 +81,6 @@ "Permite que a aplicación lea a configuración e os atallos da pantalla de inicio." "editar a configuración e os atallos da pantalla de inicio" "Permite que a aplicación cambie a configuración e os atallos da pantalla de inicio." - "%1$s non ten permiso para facer chamadas telefónicas" "Non se puido cargar o widget" "Configuración do widget" "Toca para rematar a configuración" @@ -101,6 +100,7 @@ "Cartafol: %1$s, %2$d elementos ou máis" "Fondos de pantalla" "Estilo e fondo de pantalla" + "Editar pantalla de inicio" "Axustes de Inicio" "Función desactivada polo administrador" "Permitir xirar a pantalla de inicio" diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 263525fbc6..166f446cf0 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -81,7 +81,6 @@ "ઍપને હોમમાંના સેટિંગ અને શૉર્ટકટ વાંચવાની મંજૂરી આપે છે." "હોમ સેટિંગ અને શૉર્ટકટ લખો" "ઍપને હોમમાંના સેટિંગ અને શૉર્ટકટમાં ફેરફાર કરવાની મંજૂરી આપે છે." - "%1$s ને ફોન કૉલ્સ કરવાની મંજૂરી નથી" "વિજેટ લોડ કરી શકાતું નથી" "વિજેટ સેટિંગ" "સેટઅપ પૂર્ણ કરવા માટે ટૅપ કરો" @@ -101,6 +100,7 @@ "ફોલ્ડર: %1$s, %2$d કે વધુ આઇટમ" "વૉલપેપર" "વૉલપેપર અને સ્ટાઇલ" + "હોમ સ્ક્રીનમાં ફેરફાર કરો" "હોમ સેટિંગ" "તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ" "હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 4d292e8796..5d351d7150 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -81,7 +81,6 @@ "इससे ऐप्लिकेशन, होम स्क्रीन की सेटिंग और शॉर्टकट पढ़ पाएगा." "होम स्क्रीन की सेटिंग और शॉर्टकट में बदलाव करने की अनुमति" "इससे ऐप्लिकेशन, होम स्क्रीन की सेटिंग और शॉर्टकट बदल पाएगा." - "%1$s को फ़ोन कॉल करने की अनुमति नहीं है" "विजेट को लोड नहीं किया जा सका" "विजेट की सेटिंग" "सेट अप पूरा करने के लिए टैप करें" @@ -101,6 +100,7 @@ "फ़ोल्डर: %1$s, %2$d या इससे ज़्यादा आइटम" "वॉलपेपर" "वॉलपेपर और स्टाइल" + "होम स्क्रीन में बदलाव करें" "होम पेज की सेटिंग" "आपके एडमिन ने बंद किया हुआ है" "होम स्क्रीन घुमाने की अनुमति दें" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 6aae2108f4..73e366f04c 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -81,7 +81,6 @@ "Aplikaciji omogućuje čitanje postavki i prečaca na početnom zaslonu." "pisati postavke i prečace početnog zaslona" "Aplikaciji omogućuje promjenu postavki i prečaca na početnom zaslonu." - "%1$s nema dopuštenje za telefonske pozive" "Widget se ne može učitati" "Postavke widgeta" "Dodirnite da biste dovršili postavljanje" @@ -101,6 +100,7 @@ "Mapa: %1$s, %2$d ili više stavki" "Pozadine" "Pozadina i stil" + "Uredi početni zaslon" "Postavke početnog zaslona" "Onemogućio administrator" "Dopusti zakretanje početnog zaslona" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 55c56ff134..84134ba980 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -81,7 +81,6 @@ "Lehetővé teszi az alkalmazás számára a kezdőképernyő beállításainak és parancsikonjainak olvasását." "kezdőképernyő beállításainak és parancsikonjainak írása" "Lehetővé teszi az alkalmazás számára a kezdőképernyő beállításainak és parancsikonjainak módosítását." - "A(z) %1$s nem kezdeményezhet telefonhívásokat" "Nem tölthető le a modul" "Modulbeállítások" "Koppintson a beállítás befejezéséhez" @@ -101,6 +100,7 @@ "Mappa: %1$s, %2$d vagy több elem" "Háttérképek" "Háttérkép és stílus" + "Kezdőképernyő szerkesztése" "Kezdőképernyő beállításai" "A rendszergazda letiltotta" "A kezdőképernyő elforgatásának engedélyezése" @@ -159,13 +159,13 @@ "Személyes" "Munkahelyi" "Munkaprofil" - "A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és láthatók a rendszergazda számára" + "A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és ezeket láthatja a rendszergazda" "Értem" "A munkahelyi alkalmazások szüneteltetve vannak" "A munkahelyi alkalmazásoktól nem kap értesítést." "A munkahelyi alkalmazások nem küldhetnek Önnek értesítéseket, nem használhatják az akkumulátorát, és nem férhetnek hozzá a tartózkodási helyéhez." "A munkahelyi alkalmazásoktól nem kap telefonhívásokat, szöveges üzeneteket vagy értesítéseket." - "A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és láthatók a rendszergazda számára" + "A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és ezeket láthatja a rendszergazda" "Értem" "Munkahelyi alkalmazások szüneteltetése" "Folytatás" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 13d82d629c..5fee7a8fec 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -81,7 +81,6 @@ "Հավելվածին թույլ է տալիս կարդալ հիմնական էկրանի կարգավորումներն ու դյուրանցումները։" "փոփոխել հիմնական էկրանի կարգավորումներն ու դյուրանցումները" "Հավելվածին թույլ է տալիս փոփոխել հիմնական էկրանի կարգավորումներն ու դյուրանցումները։" - "%1$s հավելվածին չի թույլատրվում հեռախոսազանգեր կատարել" "Չհաջողվեց բեռնել վիջեթը" "Վիջեթի կարգավորումներ" "Հպեք՝ կարգավորումն ավարտելու համար" @@ -101,6 +100,7 @@ "Պանակ՝ %1$s, %2$d կամ ավելի տարրեր" "Պաստառներ" "Պաստառ և ոճ" + "Փոփոխել հիմնական էկրանը" "Գլխավոր էկրանի կարգավորումներ" "Անջատվել է ձեր ադմինիստրատորի կողմից" "Թույլ տալ հիմնական էկրանի պտտումը" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index d9cba90827..7b33e9d042 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -81,7 +81,6 @@ "Mengizinkan aplikasi membaca setelan dan pintasan di layar utama." "menulis setelan dan pintasan layar utama" "Mengizinkan aplikasi mengubah setelan dan pintasan di layar utama." - "%1$s tidak diizinkan untuk melakukan panggilan telepon" "Tidak dapat memuat widget" "Setelan widget" "Ketuk untuk menyelesaikan penyiapan" @@ -101,7 +100,8 @@ "Folder: %1$s, %2$d item atau lebih" "Wallpaper" "Wallpaper & gaya" - "Setelan Layar utama" + "Edit Layar Utama" + "Setelan layar utama" "Dinonaktifkan oleh admin" "Izinkan layar utama diputar" "Saat ponsel diputar" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 84e0f7f965..5e7af5f988 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -81,7 +81,6 @@ "Leyfir forriti að lesa stillingar og flýtileiðir heimaskjás." "skrifa stillingar og flýtileiðir heimaskjás" "Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás." - "%1$s hefur ekki leyfi til að hringja símtöl" "Ekki hægt að hlaða græju" "Græjustillingar" "Ýttu til að ljúka við uppsetningu" @@ -101,6 +100,7 @@ "Mappa: %1$s, %2$d eða fleiri atriði" "Veggfóður" "Veggfóður og stíll" + "Breyta heimaskjá" "Heimastillingar" "Gert óvirkt af kerfisstjóra" "Leyfa snúning á heimaskjá" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index fce1f672ee..3699c1d1c3 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -81,7 +81,6 @@ "Consente all\'app di leggere le impostazioni e le scorciatoie nella schermata Home." "creare impostazioni e scorciatoie nella schermata Home" "Consente all\'app di modificare le impostazioni e le scorciatoie nella schermata Home." - "L\'app %1$s non è autorizzata a effettuare telefonate" "Impossibile caricare il widget" "Impostazioni widget" "Tocca per completare la configurazione" @@ -101,6 +100,7 @@ "Cartella: %1$s, %2$d o più elementi" "Sfondi" "Sfondo e stile" + "Modifica la schermata Home" "Impostazioni schermata Home" "Disattivata dall\'amministratore" "Consenti rotazione della schermata Home" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 4542589705..cbbd156993 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -81,7 +81,6 @@ "מאפשרת לאפליקציה לקרוא את ההגדרות וקיצורי הדרך בדף הבית." "כתיבת ההגדרות וקיצורי הדרך בדף הבית" "מאפשרת לאפליקציה לשנות את ההגדרות וקיצורי הדרך בדף הבית." - "%1$s אינו רשאי להתקשר" "לא ניתן לטעון את הווידג\'ט" "הגדרות הווידג\'ט" "צריך להקיש כדי לסיים את תהליך ההגדרה" @@ -101,6 +100,7 @@ "תיקייה: %1$s, %2$d פריטים או יותר" "טפטים" "טפט וסגנון" + "עריכה של מסך הבית" "הגדרות של מסך הבית" "הושבת על ידי מנהל המערכת שלך" "אישור לסיבוב מסך הבית" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 9f9df56179..7552eaf01d 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -81,7 +81,6 @@ "ホームの設定とショートカットの読み取りをアプリに許可します。" "ホームの設定とショートカットの書き込み" "ホームの設定とショートカットの変更をアプリに許可します。" - "「%1$s」から電話をかけることはできません" "ウィジェットを読み込めません" "ウィジェットの設定" "タップして設定を完了してください" @@ -101,6 +100,7 @@ "フォルダ: %1$s%2$d 件以上のアイテム" "壁紙" "壁紙とスタイル" + "ホーム画面を編集" "ホームの設定" "管理者により無効にされています" "ホーム画面の回転を許可" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index dd975fe906..602df8ec47 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -81,7 +81,6 @@ "აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვის უფლების მიცემა." "მთავარი ეკრანის პარამეტრებისა და მალსახმობების ჩაწერა" "აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების შეცვლის უფლების მიცემა." - "%1$s-ს არ აქვს სატელეფონო ზარების განხორციელების უფლება" "ვიჯეტის ჩატვირთვა ვერ ხერხდება" "ვიჯეტის პარამეტრები" "შეეხეთ დაყენების დასასრულებლად" @@ -101,6 +100,7 @@ "საქაღალდე: %1$s, %2$d ან მეტი ერთეული" "ფონები" "ფონი და სტილი" + "მთავარი ეკრანის რედაქტირება" "მთავარი გვერდის პარამეტრები" "გათიშულია თქვენი ადმინისტრატორის მიერ" "მთავარი ეკრანის შეტრიალების დაშვება" @@ -159,7 +159,7 @@ "პირადი" "სამსახური" "სამსახურის პროფილი" - "სამსახურის აპები ბეჯით არის მონიშნული და ხილულია IT ადმინისტრატორისთვის" + "სამსახურის აპები ბეჯით არის მონიშნული და ხილულია თქვენი IT ადმინისტრატორისთვის" "გასაგებია" "სამსახურის აპები დაპაუზებულია" "თქვენ არ მიიღებთ შეტყობინებებს თქვენი სამსახურის აპებიდან" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index cd45fff2bb..7012e2a036 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -81,7 +81,6 @@ "Қолданбаға негізгі экрандағы параметрлер мен таңбашаларды оқуға мүмкіндік береді." "негізгі экран параметрлері мен таңбашаларын жазу" "Қолданбаға негізгі экрандағы параметрлер мен таңбашаларды өзгертуге мүмкіндік береді." - "%1$s арқылы телефон қоңырауларын соғуға рұқсат етілмеген" "Виджетті жүктеу мүмкін емес." "Виджет параметрлері" "Реттеуді аяқтау үшін түртіңіз." @@ -101,6 +100,7 @@ "Қалта: %1$s, %2$d не одан көп элемент бар" "Тұсқағаздар" "Тұсқағаз және стиль" + "Негізгі экранды өзгерту" "Негізгі экран параметрлері" "Әкімші өшірді" "Негізгі экранды бұруға рұқсат ету" @@ -151,7 +151,7 @@ "Енін азайту" "Биіктігін азайту" "Виджет өлшемінің ені %1$s, биіктігі %2$s болып өзгертілді" - "Таңбашалар" + "Жылдам пәрмендер" "Таңбашалар мен хабарландырулар" "Бас тарту" "Жабу" @@ -167,7 +167,7 @@ "Жұмыс қолданбаларынан телефон қоңырауларын, мәтіндік хабарлар немесе хабарландырулар алмайсыз." "Жұмыс қолданбаларының танымбелгілері бар және олар әкімшіңізге көрінеді." "Түсінікті" - "Жұмыс қолданбаларын тоқтата тұру" + "Жұмыс қолданбаларын кідірту" "Қайта қосу" "Сүзгі" "Телефоннан іздеу" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 64bc3bb1e5..6aa399b95c 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -81,7 +81,6 @@ "អនុញ្ញាតឱ្យកម្មវិធីអានការកំណត់ និងផ្លូវកាត់នៅក្នុងអេក្រង់ដើម។" "សរសេរការកំណត់ និងផ្លូវកាត់សម្រាប់អេក្រង់ដើម" "អនុញ្ញាតឱ្យកម្មវិធីប្ដូរការកំណត់ និងផ្លូវកាត់នៅក្នុងអេក្រង់ដើម។" - "%1$s មិនត្រូវបានអនុញ្ញាតឲ្យធ្វើការហៅទូរស័ព្ទទេ" "មិនអាចផ្ទុក​ធាតុក្រាហ្វិក​បានទេ" "ការកំណត់​ធាតុក្រាហ្វិក" "ចុច​ដើម្បី​បញ្ចប់​ការរៀបចំ" @@ -101,6 +100,7 @@ "ថត៖ %1$s, ធាតុ %2$d ឬច្រើនជាងនេះ" "ផ្ទាំង​រូបភាព" "ផ្ទាំងរូបភាព និងរចនាប័ទ្ម" + "កែអេក្រង់ដើម" "ការកំណត់​ទំព័រដើម" "បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក" "អនុញ្ញាតការបងិ្វលអេក្រង់ដើម" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index f955277e4e..e27483e503 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -81,7 +81,6 @@ "ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಹೋಮ್ ಸ್ಕ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬರೆಯಿರಿ" "ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." - "ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು %1$s ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ" "ವಿಜೆಟ್ ಅನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ" "ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಸೆಟಪ್ ಪೂರ್ಣಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ" @@ -101,6 +100,7 @@ "ಫೋಲ್ಡರ್: %1$s, %2$d ಅಥವಾ ಹೆಚ್ಚಿನ ಐಟಂಗಳು" "ವಾಲ್‌ಪೇಪರ್‌ಗಳು" "ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಶೈಲಿ" + "ಹೋಮ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ" "ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" "ಹೋಮ್ ಸ್ಕ್ರೀನ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 4d621ec5dc..95be8e96ac 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -81,7 +81,6 @@ "앱이 홈에 있는 설정 및 바로가기를 읽을 수 있도록 허용합니다." "홈 설정 및 바로가기 쓰기" "앱이 홈에 있는 설정 및 바로가기를 변경할 수 있도록 허용합니다." - "%1$s에서 전화를 걸 수 없습니다." "위젯을 로드할 수 없습니다." "위젯 설정" "탭하여 설정을 완료하세요." @@ -101,6 +100,7 @@ "폴더: %1$s, 항목 %2$d개 이상" "배경화면" "배경화면 및 스타일" + "홈 화면 수정" "홈 설정" "관리자가 사용 중지함" "홈 화면 회전 허용" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 0fe280205d..d0048aca31 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -81,7 +81,6 @@ "Колдонмого үйдүн параметрлерин жана ыкчам баскычтарын окууга уруксат берет." "үйдүн параметрлерин жана ыкчам баскычтарын жазуу" "Колдонмого үйдүн параметрлерин жана ыкчам баскычтарын өзгөртүүгө уруксат берет." - "%1$s телефон чалууларды аткарууга уруксаты жок" "Виджет жүктөлбөй жатат" "Виджеттин параметрлери" "Аягына чейин тууралоо үчүн басып коюңуз" @@ -101,6 +100,7 @@ "%1$s папкасындагы объекттер: %2$d же андан көбүрөөк" "Тушкагаздар" "Тушкагаз жана стиль" + "Башкы экранды түзөтүү" "Башкы бет параметрлери" "Администраторуңуз өчүрүп койгон" "Башкы экранды бурууга уруксат берүү" diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 72eb3faea9..21481787a5 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -81,7 +81,6 @@ "ອະນຸຍາດໃຫ້ແອັບອ່ານການຕັ້ງຄ່າ ແລະ ທາງລັດໃນໜ້າຫຼັກ." "ຂຽນການຕັ້ງຄ່າໜ້າຫຼັກ ແລະ ທາງລັດ" "ອະນຸຍາດໃຫ້ແອັບປ່ຽນການຕັ້ງຄ່າ ແລະ ທາງລັດໃນໜ້າຫຼັກ." - "%1$s ບໍ່​ໄດ້​ຮັບ​ອະ​ນຸ​ຍາດ​ໃຫ້​ໂທ" "ບໍ່ສາມາດໂຫຼດວິດເຈັດໄດ້" "ການຕັ້ງຄ່າວິດເຈັດ" "ແຕະເພື່ອຕັ້ງຄ່າໃຫ້ແລ້ວ" @@ -101,6 +100,7 @@ "ໂຟນເດີ: %1$s, %2$d ຫຼື ລາຍການເພີ່ມເຕີມ" "ພາບພື້ນຫຼັງ" "ຮູບພື້ນຫຼັງ ແລະ ຮູບແບບ" + "ແກ້ໄຂໂຮມສະກຣີນ" "ການຕັ້ງຄ່າໜ້າຫຼັກ" "ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ" "ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍຢູ່ໂຮມສະກຣີນໄດ້" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 0f0237620f..2ea7174933 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -81,7 +81,6 @@ "Programai leidžiama skaityti pagrindinio ekrano nustatymus ir sparčiuosius klavišus." "rašyti pagrindinio ekrano nustatymus ir sparčiuosius klavišus" "Programai leidžiama keisti pagrindinio ekrano nustatymus ir sparčiuosius klavišus." - "„%1$s“ neleidžiama skambinti" "Nepavyko įkelti valdiklio" "Valdiklio nustatymai" "Palieskite, kad užbaigtumėte sąranką" @@ -101,6 +100,7 @@ "Aplankas: „%1$s“, elementų: %2$d ar daugiau" "Ekrano fonai" "Ekrano fonas ir stilius" + "Redaguoti pagrindinį ekraną" "„Home“ nustatymai" "Išjungė administratorius" "Leisti pasukti pagrindinį ekraną" diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 150af9b66b..d0011e043f 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -81,7 +81,6 @@ "Ļauj lietotnei lasīt iestatījumus un saīsnes sākuma ekrānā." "sākuma ekrāna iestatījumu un saīšņu rakstīšana" "Ļauj lietotnei mainīt iestatījumus un saīsnes sākuma ekrānā." - "Lietotnei %1$s nav atļauts veikt tālruņa zvanus." "Nevar ielādēt logrīku." "Logrīka iestatījumi" "Pieskarieties, lai pabeigtu iestatīšanu" @@ -101,6 +100,7 @@ "Mape %1$s, vienumu skaits mapē: vismaz %2$d" "Fona tapetes" "Fona tapete un stils" + "Rediģēt sākuma ekrānu" "Sākumlapas iestatījumi" "Atspējojis administrators" "Atļaut sākuma ekrāna pagriešanu" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 13ff08ad4a..47127a7e7d 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -81,7 +81,6 @@ "Овозможува апликацијата да ги чита поставките и кратенките на почетната страница." "да пишува поставки и кратенки на почетна страница" "Овозможува апликацијата да ги менува поставките и кратенките на почетната страница." - "%1$s нема дозвола за телефонски повици" "Не може да се вчита виџетот" "Поставки за виџет" "Допрете за да го завршите поставувањето" @@ -101,6 +100,7 @@ "Папка: %1$s, %2$d или повеќе ставки" "Тапети" "Тапет и стил" + "Изменете го почетниот екран" "Поставки за почетен екран" "Оневозможено од администраторот" "Дозволи ротирање на почетниот екран" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index e023df8c74..59827f28eb 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -81,7 +81,6 @@ "ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു." "ഹോം ക്രമീകരണവും കുറുക്കുവഴികളും എഴുതുക" "ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ ആപ്പിനെ അനുവദിക്കുന്നു." - "ഫോൺ കോൾ ചെയ്യാൻ %1$s എന്നതിനെ അനുവദിച്ചിട്ടില്ല" "വിജറ്റ് ലോഡ് ചെയ്യാനാകുന്നില്ല" "വിജറ്റ് ക്രമീകരണം" "സജ്ജീകരണം പൂർത്തിയാക്കാൻ ടാപ്പ് ചെയ്യുക" @@ -101,6 +100,7 @@ "ഫോൾഡർ: %1$s, %2$d അല്ലെങ്കിൽ അതിലധികം ഇനങ്ങൾ" "വാൾപേപ്പർ" "വാൾപേപ്പറും സ്‌റ്റൈലും" + "ഹോം സ്‌ക്രീൻ എഡിറ്റ് ചെയ്യുക" "ഹോം ക്രമീകരണം" "അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു" "ഹോം സ്ക്രീൻ റൊട്ടേഷൻ അനുവദിക്കുക" @@ -164,7 +164,7 @@ "ഔദ്യോഗിക ആപ്പുകൾ തൽക്കാലം നിർത്തിയിരിക്കുന്നു" "ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് നിങ്ങൾക്ക് അറിയിപ്പുകളൊന്നും ലഭിക്കില്ല" "നിങ്ങൾക്ക് അറിയിപ്പുകൾ അയയ്ക്കാനോ ബാറ്ററി ഉപയോഗിക്കാനോ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാനോ നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾക്ക് കഴിയില്ല" - "Work ആപ്പുകളിൽ നിന്ന് നിങ്ങൾക്ക് ഫോൺ കോളുകളും ടെക്സ്റ്റ് മെസേജുകളും അറിയിപ്പുകളും ലഭിക്കില്ല" + "വർക്ക് ആപ്പുകളിൽ നിന്ന് നിങ്ങൾക്ക് ഫോൺ കോളുകളും ടെക്സ്റ്റ് മെസേജുകളും അറിയിപ്പുകളും ലഭിക്കില്ല" "ഔദ്യോഗിക ആപ്പുകൾക്ക് ബാഡ്‌ജ് നൽകിയിരിക്കുന്നു, അവ നിങ്ങളുടെ ഐടി അഡ്‌മിന് കാണാനും കഴിയും" "മനസ്സിലായി" "ഔദ്യോഗിക ആപ്പുകൾ താൽക്കാലികമായി നിർത്തുക" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 79adc913f1..d24f5fe15b 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -81,7 +81,6 @@ "Аппад нүүрэн дэх тохиргоо болон товчлолыг уншихыг зөвшөөрнө." "нүүрний тохиргоо болон товчлолыг бичих" "Аппад нүүрэн дэх тохиргоо болон товчлолыг өөрчлөхийг зөвшөөрнө." - "%1$s утасны дуудлага хийх боломжгүй" "Жижиг хэрэгслийг ачаалах боломжгүй" "Виджетийн тохиргоо" "Тохируулгыг дуусгахын тулд товшино уу" @@ -101,6 +100,7 @@ "Фолдер: %1$s, %2$d эсвэл үүнээс олон зүйл" "Дэлгэцийн зураг" "Дэлгэцийн зураг, загвар" + "Үндсэн нүүрийг засах" "Нүүр хуудасны тохиргоо" "Таны админ идэвхгүй болгосон" "Үндсэн нүүрийг эргүүлэхийг зөвшөөрөх" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index ff9cb3813e..b74a8f50ed 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -81,7 +81,6 @@ "अ‍ॅपला होममधील सेटिंग्ज आणि शॉर्टकट वाचण्याची अनुमती देते." "होम सेटिंग्ज आणि शॉर्टकट लिहा" "अ‍ॅपला होममधील सेटिंग्ज आणि शॉर्टकट बदलण्याची अनुमती देते." - "%1$s ला फोन कॉल करण्याची अनुमती नाही" "विजेट लोड करू शकत नाही" "विजेटची सेटिंग्ज" "सेटअप पूर्ण करण्‍यासाठी टॅप करा" @@ -101,6 +100,7 @@ "फोल्डर: %1$s, %2$d किंवा त्याहून अधिक आयटम" "वॉलपेपर" "वॉलपेपर आणि शैली" + "होम स्क्रीन संपादित करा" "होम सेटिंग्‍ज" "आपल्या प्रशासकाने अक्षम केले" "होम स्क्रीन फिरवण्‍याची अनुमती द्या" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 29845cdf87..7d1a4d172a 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -81,7 +81,6 @@ "Membenarkan apl membaca tetapan dan pintasan di skrin utama." "menulis tetapan dan pintasan skrin utama" "Membenarkan apl menukar tetapan dan pintasan di skrin utama." - "%1$s tidak dibenarkan membuat panggilan telefon" "Tidak dapat memuatkan widget" "Tetapan widget" "Ketik untuk menyelesaikan persediaan" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d atau lebih banyak item" "Hiasan latar" "Kertas dinding & gaya" + "Edit Skrin Utama" "Tetapan skrin utama" "Dilumpuhkan oleh pentadbir anda" "Benarkan putaran skrin utama" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 6c11a61bc0..1a6b0de1e6 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -81,7 +81,6 @@ "ပင်မတွင်ရှိသော ဆက်တင်များနှင့် ဖြတ်လမ်းလင့်ခ်များကို အက်ပ်အား ဖတ်ခွင့်ပြုနိုင်သည်။" "ပင်မဆက်တင်နှင့် ဖြတ်လမ်းလင့်ခ်များ ရေးသားခြင်း" "ပင်မတွင်ရှိသော ဆက်တင်များနှင့် ဖြတ်လမ်းလင့်ခ်များကို အက်ပ်အား ပြောင်းခွင့်ပြုနိုင်သည်။" - "%1$sသည် ဖုန်းခေါ်ဆိုခွင့် မရှိပါ" "ဝိဂျက်ကို ဖွင့်၍မရပါ" "ဝိဂျက်ဆက်တင်များ" "စနစ်ထည့်သွင်းခြင်း အပြီးသတ်ရန် တို့ပါ" @@ -101,6 +100,7 @@ "ဖိုင်တွဲ - %1$s%2$d သို့မဟုတ် နောက်ထပ်ဖိုင်များ" "နောက်ခံများ" "နောက်ခံနှင့် ပုံစံ" + "ပင်မစာမျက်နှာ တည်းဖြတ်ရန်" "ပင်မဆက်တင်များ" "သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်" "ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုခြင်း" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 1b1941cfc6..dbcff53c05 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -81,7 +81,6 @@ "Lar appen lese innstillingene og snarveiene på startsiden." "angi startsideinnstillinger og -snarveier" "Lar appen endre innstillingene og snarveiene på startsiden." - "%1$s har ikke tillatelse til å ringe" "Kan ikke laste inn modulen" "Modulinnstillinger" "Trykk for å fullføre konfigureringen" @@ -101,6 +100,7 @@ "Mappe: %1$s, %2$d eller flere elementer" "Bakgrunner" "Bakgrunn og stil" + "Endre startsiden" "Startsideinnstillinger" "Administratoren har slått av funksjonen" "Tillat at startskjermen roterer" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index d8e372af93..81095c8bed 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -81,7 +81,6 @@ "एपलाई होम स्क्रिनबाट सेटिङ र सर्टकटहरू रिड गर्ने अनुमति दिन्छ।" "होम स्क्रिनका सेटिङ र सर्टकटहरू राइट गरियोस्" "एपलाई होम स्क्रिनबाट सेटिङ र सर्टकट बदल्ने अनुमति दिन्छ" - "%1$s ले फोन कलहरू गर्न अनुमति छैन" "विजेट लोड गर्न सकिएन" "विजेटका सेटिङ" "सेटअप पूरा गर्न ट्याप गर्नुहोस्" @@ -101,6 +100,7 @@ "फोल्डर: %1$s, %2$d वा सोभन्दा बढी वस्तुहरू" "वालपेपरहरु" "वालपेपर तथा शैली" + "होम स्क्रिन बदल्नुहोस्" "होम पेजका सेटिङहरू" "तपाईँको प्रशासकद्वारा असक्षम गरिएको" "होम स्क्रिन रोटेट हुन दिइयोस्" @@ -171,6 +171,6 @@ "सुचारु गर्नुहोस्" "फिल्टर" "आफ्नो फोन खोज्नुहोस्" - "आफ्नो ट्याब्लेट खोज्नुहोस्" + "आफ्नो ट्याबलेटमा खोज्नुहोस्" "कार्य पूरा गर्न सकिएन: %1$s" diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml index f331361f71..4dd3849cf8 100644 --- a/res/values-night-v31/colors.xml +++ b/res/values-night-v31/colors.xml @@ -26,4 +26,27 @@ @android:color/system_neutral1_700 @android:color/system_neutral2_200 + + @android:color/system_neutral1_100 + + @android:color/system_neutral1_100 + + @android:color/system_neutral2_200 + + @android:color/system_accent2_700 + + @android:color/system_accent1_800 + + @android:color/system_accent1_200 + + @android:color/system_neutral2_200 + + @android:color/system_accent1_200 + + @android:color/system_accent1_800 + + @android:color/system_neutral2_200 + + @android:color/system_neutral2_700 + \ No newline at end of file diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 97b650b853..2241a58b87 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -81,7 +81,6 @@ "De app toestaan de instellingen en snelkoppelingen op het startscherm te lezen." "instellingen en snelkoppelingen op startscherm wijzigen" "De app toestaan de instellingen en snelkoppelingen op het startscherm te wijzigen." - "%1$s mag niet bellen" "Kan widget niet laden" "Widgetinstellingen" "Tik om instellen af te ronden" @@ -101,6 +100,7 @@ "Map: %1$s, %2$d of meer items" "Achtergrond" "Achtergrond en stijl" + "Startscherm bewerken" "Instellingen start" "Uitgezet door je beheerder" "Draaien van startscherm toestaan" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 304e13f42e..abb33cde79 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -81,7 +81,6 @@ "ହୋମରେ ଥିବା ସେଟିଂସ ଏବଂ ସର୍ଟକଟଗୁଡ଼ିକୁ ପଢ଼ିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।" "ହୋମ ସେଟିଂସ ଏବଂ ସର୍ଟକଟଗୁଡ଼ିକୁ ଲେଖନ୍ତୁ" "ହୋମରେ ଥିବା ସେଟିଂସ ଏବଂ ସର୍ଟକଟଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।" - "ଫୋନ୍‌ କଲ୍‌ କରିବାକୁ %1$sକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ" "ୱିଜେଟ୍ ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ" "ୱିଜେଟ ସେଟିଂସ" "ସେଟଅପ ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ଟାପ କରନ୍ତୁ" @@ -101,6 +100,7 @@ "ଫୋଲ୍ଡର୍: %1$s, %2$d କିମ୍ବା ଅଧିକ ଆଇଟମ୍" "ୱାଲପେପର୍‌" "ୱାଲପେପର ଏବଂ ଷ୍ଟାଇଲ" + "ହୋମ ସ୍କ୍ରିନକୁ ଏଡିଟ କରନ୍ତୁ" "ହୋମ ସେଟିଂସ" "ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି" "ହୋମ ସ୍କ୍ରିନ ରୋଟେସନକୁ ଅନୁମତି ଦିଅନ୍ତୁ" @@ -159,13 +159,13 @@ "ବ୍ୟକ୍ତିଗତ" "ୱାର୍କ" "ୱର୍କ ପ୍ରୋଫାଇଲ୍‌" - "ୱାର୍କ ଆପ୍ସ ବ୍ୟାଜ୍ କରାଯାଇଛି ଏବଂ ସେଗୁଡ଼ିକ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହେଉଛି" + "ୱାର୍କ ଆପ୍ସ ବ୍ୟାଜ କରାଯାଇଛି ଏବଂ ସେଗୁଡ଼ିକ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହେଉଛି" "ବୁଝିଗଲି" "ୱାର୍କ ଆପ୍ସ ବିରତ କରାଯାଇଛି" "ଆପଣ ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସରୁ ବିଜ୍ଞପ୍ତି ପାଇବେ ନାହିଁ" "ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସ ଆପଣଙ୍କୁ ବିଜ୍ଞପ୍ତି ପଠାଇପାରିବ ନାହିଁ, ଆପଣଙ୍କ ବ୍ୟାଟେରୀକୁ ବ୍ୟବହାର କରିପାରିବ ନାହିଁ କିମ୍ବା ଆପଣଙ୍କର ଲୋକେସନକୁ ଆକ୍ସେସ କରିପାରିବ ନାହିଁ" "ଆପଣ ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସରୁ ଫୋନ କଲ, ଟେକ୍ସଟ ମେସେଜ କିମ୍ବା ବିଜ୍ଞପ୍ତି ପାଇବେ ନାହିଁ" - "ୱାର୍କ ଆପ୍ସ ବ୍ୟାଜ୍ କରାଯାଇଛି ଏବଂ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦେଖାଯାଉଛି" + "ୱାର୍କ ଆପ୍ସ ବ୍ୟାଜ କରାଯାଇଛି ଏବଂ ସେଗୁଡ଼ିକ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହେଉଛି" "ବୁଝିଗଲି" "ୱାର୍କ ଆପ୍ସ ବିରତ କରନ୍ତୁ" "ପୁଣି ଚାଲୁ କରନ୍ତୁ" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 24a5f7f6bc..d8e68dc59f 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -81,7 +81,6 @@ "ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" "ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਲਿਖੋ" "ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" - "%1$s ਨੂੰ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ" "ਵਿਜੇਟ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" "ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ" "ਸੈੱਟਅੱਪ ਪੂਰਾ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ" @@ -101,6 +100,7 @@ "ਫੋਲਡਰ: %1$s, %2$d ਜਾਂ ਹੋਰ ਆਈਟਮਾਂ" "ਵਾਲਪੇਪਰ" "ਵਾਲਪੇਪਰ ਅਤੇ ਸਟਾਈਲ" + "ਹੋਮ ਸਕ੍ਰੀਨ ਦਾ ਸੰਪਾਦਨ ਕਰੋ" "ਹੋਮ ਸੈਟਿੰਗਾਂ" "ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ" "ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ" @@ -159,13 +159,13 @@ "ਨਿੱਜੀ" "ਕੰਮ ਸੰਬੰਧੀ" "ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ" - "ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਬੈਜ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਣਗੀਆਂ" + "ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਬੈਜ ਕੀਤਾ ਗਿਆ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਣਗੀਆਂ" "ਸਮਝ ਲਿਆ" "ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ" "ਤੁਹਾਨੂੰ ਆਪਣੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਹੋਣਗੀਆਂ" "ਤੁਹਾਡੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੁਹਾਨੂੰ ਸੂਚਨਾਵਾਂ ਨਹੀਂ ਭੇਜ ਸਕਦੀਆਂ, ਤੁਹਾਡੀ ਬੈਟਰੀ ਨਹੀਂ ਵਰਤ ਸਕਦੀਆਂ ਜਾਂ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕਰ ਸਕਦੀਆਂ" "ਤੁਹਾਨੂੰ ਆਪਣੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਫ਼ੋਨ ਕਾਲਾਂ, ਲਿਖਤ ਸੁਨੇਹੇ ਜਾਂ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਹੋਣਗੀਆਂ" - "ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਬੈਜ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਣਗੀਆਂ" + "ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਬੈਜ ਕੀਤਾ ਗਿਆ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਣਗੀਆਂ" "ਸਮਝ ਲਿਆ" "ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਰੋਕੋ" "ਰੋਕ ਹਟਾਓ" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 7239f9fdd6..464a058a05 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -81,7 +81,6 @@ "Umożliwia aplikacji odczytywanie ustawień i skrótów na ekranie głównym." "Zapisuje ustawienia i skróty na ekranie głównym" "Umożliwia aplikacji zmianę ustawień i skrótów na ekranie głównym." - "%1$s nie może wykonywać połączeń telefonicznych" "Nie udało się załadować widżetu" "Ustawienia widżetu" "Kliknij, aby dokończyć konfigurację" @@ -101,13 +100,14 @@ "Folder: %1$s, liczba elementów: %2$d lub więcej" "Tapety" "Tapeta i styl" + "Edytuj ekran główny" "Ustawienia ekranu głównego" "Funkcja wyłączona przez administratora" "Zezwalaj na obrót ekranu głównego" "Po obróceniu telefonu" "Kropki powiadomień" - "Włączono" - "Wyłączono" + "Włączone" + "Wyłączone" "Wymagany jest dostęp do powiadomień" "Aby pokazywać kropki powiadomień, włącz powiadomienia aplikacji %1$s" "Zmień ustawienia" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index e9445cf700..dcbbe1dd3c 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -81,7 +81,6 @@ "Permite que a app leia as definições e os atalhos no ecrã principal." "escrever definições e atalhos do ecrã principal" "Permite que a app altere as definições e os atalhos no ecrã principal." - "O %1$s não tem autorização para efetuar chamadas telefónicas" "Não é possível carregar o widget" "Definições de widget" "Toque para concluir a configuração" @@ -101,6 +100,7 @@ "Pasta: %1$s, %2$d ou mais itens" "Imagens de fundo" "Imagem fundo/estilo" + "Editar ecrã principal" "Definições de início" "Desativada pelo gestor" "Permitir rotação do ecrã principal" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 72dd608fad..d63406cd1d 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -81,7 +81,6 @@ "Permite que o app leia as configurações e os atalhos na tela inicial." "gravar configurações e atalhos da tela inicial" "Permite que o app mude as configurações e os atalhos na tela inicial." - "%1$s não tem permissão para fazer chamadas" "Não é possível carregar o widget" "Configurações de widget" "Toque para concluir a configuração" @@ -101,12 +100,13 @@ "Pasta: %1$s, %2$d ou mais itens" "Planos de fundo" "Plano de fundo e estilo" + "Editar tela inicial" "Configurações da tela inicial" "Desativado pelo administrador" "Permitir a rotação da tela inicial" "Quando o smartphone for girado" "Pontos de notificação" - "Ativado" + "Ativados" "Desativado" "Acesso a notificações necessário" "Para mostrar pontos de notificação, ative as notificações de app para %1$s" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index dbfbf766b0..7a63581c59 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -81,7 +81,6 @@ "Permite aplicației să citească setările și comenzile rapide de pe ecranul de pornire." "scrie setările și comenzile rapide de pe ecranul de pornire" "Permite aplicației să modifice setările și comenzile rapide de pe ecranul de pornire." - "%1$s nu are permisiunea de a apela" "Widgetul nu poate fi încărcat" "Setări pentru widget" "Atinge pentru a finaliza configurarea" @@ -101,6 +100,7 @@ "Dosar: %1$s, %2$d sau mai multe elemente" "Imagini de fundal" "Imagine de fundal și stil" + "Editează ecranul de pornire" "Setări ecran de pornire" "Dezactivată de administrator" "Permite rotirea ecranului de pornire" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 134004da14..5735ba45ed 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -81,7 +81,6 @@ "Приложение получит доступ к данным о настройках и ярлыках на главном экране." "Изменение настроек и ярлыков на главном экране" "Приложение сможет изменять настройки и ярлыки на главном экране." - "Приложение %1$s не может делать телефонные звонки" "Не удается загрузить виджет." "Настройки виджета" "Нажмите, чтобы завершить настройку." @@ -101,6 +100,7 @@ "Папка \"%1$s\" (объектов: %2$d или больше)" "Обои" "Обои и стиль" + "Изменить главный экран" "Главный экран" "Функция отключена администратором" "Разрешить поворачивать главный экран" @@ -159,13 +159,13 @@ "Личные" "Рабочие" "Рабочий профиль" - "У рабочих приложений есть специальная пометка. Они видны системному администратору." + "У рабочих приложений есть специальный значок. Они видны системному администратору." "ОК" "Рабочие приложения приостановлены" "Вы не будете получать уведомления от рабочих приложений." "Рабочие приложения не могут отправлять уведомления, расходовать заряд батареи и получать доступ к данным о вашем местоположении." "Вы не будете получать вызовы, текстовые сообщения и уведомления от рабочих приложений." - "У рабочих приложений есть специальная пометка. Они видны системному администратору." + "У рабочих приложений есть специальный значок. Они видны системному администратору." "ОК" "Приостановить рабочие приложения" "Возобновить" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 01d6ba0026..a7ea98be0c 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -81,7 +81,6 @@ "මුල් පිටුවේ ඇති සැකසීම් සහ කෙටි මං කියවීමට යෙදුමට ඉඩ දෙයි." "මුල් පිටු සැකසීම් සහ කෙටි මං ලියන්න" "මුල් පිටුවේ සැකසීම් සහ කෙටි මං ඉවත් කිරීමට යෙදුමට ඉඩ දෙයි." - "%1$s හට දුරකථන ඇමතුම් සිදු කිරීමට ඉඩ නොදේ" "විජට් පූරණය කළ නොහැකිය" "විජට් සැකසීම්" "පිහිටුවීම අවසන් කිරීමට තට්ටු කරන්න" @@ -101,6 +100,7 @@ "ෆෝල්ඩර: %1$s, අයිතම %2$dක් හෝ වැඩි ගණනක්" "වෝල්පේපර" "වෝල්පේපරය සහ මෝස්තරය" + "මුල් තිරය සංස්කරණය කරන්න" "නිවසේ සැකසීම්" "ඔබගේ පරිපාලක විසින් අබල කරන ලදී" "මුල් තිරය කරකැවීමට ඉඩ දෙන්න" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 2c257b7709..434e416327 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -81,7 +81,6 @@ "Povoľuje aplikácii čítať nastavenia a odkazy na ploche." "zápis nastavení a odkazov plochy" "Povoľuje aplikácii meniť nastavenia a odkazy na ploche." - "Aplikácia %1$s nemá povolenie uskutočňovať telefonické hovory" "Miniaplikáciu sa nepodarilo načítať" "Nastavenia miniaplikácie" "Nastavenie dokončíte klepnutím" @@ -101,6 +100,7 @@ "Priečinok: %1$s, %2$d alebo viac položiek" "Tapety" "Tapeta a štýl" + "Upraviť plochu" "Nastavenia plochy" "Zakázané vaším správcom" "Povoliť otáčanie plochy" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 2fd10ecd47..cad7f40064 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -81,7 +81,6 @@ "Aplikaciji dovoli branje nastavitev in bližnjic na začetnem zaslonu." "zapisovanje nastavitev in bližnjic začetnega zaslona" "Aplikaciji dovoli spreminjanje nastavitev in bližnjic na začetnem zaslonu." - "Aplikaciji %1$s ni dovoljeno opravljanje klicev" "Pripomočka ni mogoče naložiti." "Nastavitve pripomočka" "Dotaknite se, da dokončate postopek nastavitve." @@ -101,6 +100,7 @@ "Mapa: %1$s, %2$d ali več elementov" "Ozadja" "Zaslonsko ozadje in slog" + "Urejanje začetnega zaslona" "Domače nastavitve" "Onemogočil skrbnik." "Dovoli sukanje začetnega zaslona" diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 994fa9891a..ff97f00143 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -81,7 +81,6 @@ "Lejon aplikacionin që të lexojë cilësimet dhe shkurtoret në ekranin bazë." "shkruaj cilësimet dhe shkurtoret e ekranit bazë" "Lejon aplikacionin që të ndryshojë cilësimet dhe shkurtoret në ekranin bazë." - "%1$s nuk lejohet të kryejë telefonata" "S\'mund të ngarkohet miniaplikacioni" "Cilësimet e miniaplikacionit" "Trokit për të përfunduar konfigurimin" @@ -101,6 +100,7 @@ "Dosja: %1$s, %2$d ose më shumë artikuj" "Imazhet e sfondit" "Imazhi i sfondit dhe stili" + "Modifiko ekranin bazë" "Cilësimet e ekranit bazë" "Çaktivizuar nga administratori" "Lejo rrotullimin e ekranit bazë" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 544ef0c04f..668ce5a0fa 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -81,7 +81,6 @@ "Дозвољава апликацији да чита подешавања и пречице на почетном екрану." "уписивање подешавања и пречица на почетном екрану" "Дозвољава апликацији да мења подешавања и пречице на почетном екрану." - "%1$s нема дозволу за упућивање телефонских позива" "Учитавање виџета није успело" "Подешавања виџета" "Додирните да бисте довршили подешавање" @@ -101,6 +100,7 @@ "Фолдер: %1$s, %2$d или више ставки" "Позадине" "Позадина и стил" + "Измени почетни екран" "Подешавања почетног екрана" "Администратор је онемогућио" "Дозволи ротацију почетног екрана" @@ -156,8 +156,8 @@ "Одбаци" "Затвори" "Обавештење је одбачено" - "Личне" - "Пословне" + "Лично" + "Посао" "Пословни профил" "Пословне апликације су означене значком и ИТ администратор може да их види" "Важи" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 9d7f650e3e..dba173d195 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -81,7 +81,6 @@ "Tillåter att appen läser inställningar och genvägar på startskärmen." "skriva inställningar och genvägar på startskärmen" "Tillåter att appen ändrar inställningar och genvägar på startskärmen." - "%1$s har inte behörighet att ringa samtal" "Det gick inte att läsa in widgeten" "Widgetinställningar" "Tryck för att slutföra konfigureringen" @@ -101,6 +100,7 @@ "Mapp: %1$s, %2$d eller fler objekt" "Bakgrunder" "Bakgrund och utseende" + "Redigera startskärm" "Startinställningar" "Inaktiverat av administratören" "Tillåt rotering av startskärmen" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 2fbf7aa5f0..b992037748 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -81,7 +81,6 @@ "Huruhusu programu kusoma mipangilio na njia za mikato katika skrini ya kwanza." "kuandika mipangilio ya skrini ya kwanza na njia za mkato" "Huruhusu programu kubadilisha mipangilio na njia za mkato katika skrini ya kwanza." - "%1$s hairuhusiwi kupiga simu" "Imeshindwa kupakia wijeti" "Mipangilio ya wijeti" "Gusa ili umalize kuweka mipangilio" @@ -101,6 +100,7 @@ "Folda: %1$s, vipengee %2$d au zaidi" "Mandhari" "Mandhari na mtindo" + "Badilisha Skrini ya Kwanza" "Mipangilio ya mwanzo" "Imezimwa na msimamizi wako" "Ruhusu kipengele cha kuzungusha skrini ya kwanza" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index bbf22a4ddc..29f1206275 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -81,7 +81,6 @@ "முகப்புத் திரையிலுள்ள அமைப்புகளையும் ஷார்ட்கட்களையும் படிக்க ஆப்ஸை அனுமதிக்கும்." "முகப்புத் திரையின் அமைப்புகளையும் ஷார்ட்கட்களையும் எழுதுதல்" "முகப்புத் திரையிலுள்ள அமைப்புகளையும் ஷார்ட்கட்களையும் மாற்ற ஆப்ஸை அனுமதிக்கும்." - "ஃபோன் அழைப்புகள் செய்ய, %1$s அனுமதிக்கப்படவில்லை" "விட்ஜெட்டை ஏற்ற முடியவில்லை" "விட்ஜெட் அமைப்புகள்" "அமைவை நிறைவுசெய்யத் தட்டவும்" @@ -101,6 +100,7 @@ "ஃபோல்டர்: %1$s, %2$d அல்லது அதற்கு அதிகமான ஃபைல்கள்" "வால்பேப்பர்கள்" "வால்பேப்பர் & ஸ்டைல்" + "முகப்புத் திரையில் மாற்று" "முகப்பு அமைப்புகள்" "உங்கள் நிர்வாகி முடக்கியுள்ளார்" "முகப்புத் திரை சுழற்சியை அனுமதித்தல்" @@ -159,7 +159,7 @@ "தனிப்பட்டவை" "பணி" "பணிக் கணக்கு" - "பணி ஆப்ஸில் பேட்ஜ் இடப்பட்டுள்ளன. உங்கள் IT நிர்வாகியால் அவற்றைப் பார்க்க முடியும்" + "பணி ஆப்ஸில் பேட்ஜ் இடப்பட்டிருக்கும், உங்கள் IT நிர்வாகியால் பணி ஆப்ஸைப் பார்க்க முடியும்" "முடிந்தது" "பணி ஆப்ஸ் இடைநிறுத்தப்பட்டுள்ளன" "உங்கள் பணி ஆப்ஸிலிருந்து அறிவிப்புகளைப் பெறமாட்டீர்கள்" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 88fca12453..35b5c16ae0 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -81,7 +81,6 @@ "హోమ్‌లో సెట్టింగ్‌లు, షార్ట్‌కట్‌లను చదవడానికి యాప్‌ను అనుమతిస్తుంది." "హోమ్ సెట్టింగ్‌లు, షార్ట్‌కట్‌లను రాయండి" "హోమ్‌లో సెట్టింగ్‌లు, షార్ట్‌కట్‌లను మార్చడానికి యాప్‌ను అనుమతిస్తుంది." - "ఫోన్ కాల్స్‌ను చేసేందుకు %1$sకి అనుమతి లేదు" "విడ్జెట్‌ను లోడ్ చేయడం సాధ్యం కాలేదు" "విడ్జెట్ సెట్టింగ్‌లు" "సెటప్‌ను ముగించడానికి ట్యాప్ చేయండి" @@ -101,6 +100,7 @@ "ఫోల్డర్: %1$s, %2$d లేదా అంతకంటే ఎక్కువ ఐటెమ్‌లు" "వాల్‌పేపర్‌లు" "వాల్‌పేపర్ & స్టయిల్" + "మొదటి స్క్రీన్‌ను ఎడిట్ చేయండి" "మొదటి స్క్రీన్ సెట్టింగ్‌లు" "మీ నిర్వాహకులు నిలిపివేసారు" "మొదటి స్క్రీన్ రొటేషన్‌ను అనుమతించండి" @@ -167,7 +167,7 @@ "మీ వర్క్ యాప్‌ల నుండి మీకు ఫోన్ కాల్స్, టెక్స్ట్ మెసేజ్‌లు, లేదా నోటిఫికేషన్‌లు అందవు" "వర్క్ యాప్‌లకు బ్యాడ్జ్ ఉంటుంది, అవి మీ IT అడ్మిన్‌కు కనిపిస్తాయి" "అర్థమైంది" - "వర్క్ యాప్‌లను పాజ్ చేయి" + "వర్క్ యాప్‌లను పాజ్ చేయండి" "పాజ్ నుండి తీసివేయండి" "ఫిల్టర్ చేయి" "మీ ఫోన్‌లో సెర్చ్ చేయండి" diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 6bcc09e9f3..35cab0dd60 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -81,7 +81,6 @@ "อนุญาตให้แอปอ่านการตั้งค่าและทางลัดในหน้าแรก" "เขียนการตั้งค่าและทางลัดในหน้าแรก" "อนุญาตให้แอปเปลี่ยนการตั้งค่าและทางลัดในหน้าแรก" - "%1$s ไม่ได้รับอนุญาตให้โทรออก" "โหลดวิดเจ็ตไม่ได้" "การตั้งค่าวิดเจ็ต" "แตะเพื่อสิ้นสุดการตั้งค่า" @@ -101,6 +100,7 @@ "โฟลเดอร์: %1$s, อย่างน้อย %2$d รายการ" "วอลเปเปอร์" "วอลเปเปอร์และรูปแบบ" + "แก้ไขหน้าจอหลัก" "การตั้งค่าหน้าจอหลัก" "ปิดใช้โดยผู้ดูแลระบบ" "อนุญาตให้หมุนหน้าจอหลัก" @@ -161,7 +161,7 @@ "โปรไฟล์งาน" "แอปงานจะติดป้ายไว้และผู้ดูแลระบบไอทีจะมองเห็น" "รับทราบ" - "แอปงานปิดอยู่" + "แอปงานหยุดชั่วคราว" "คุณจะไม่ได้รับการแจ้งเตือนจากแอปงาน" "แอปงานจะส่งการแจ้งเตือน ใช้แบตเตอรี่ หรือเข้าถึงตำแหน่งของคุณไม่ได้" "คุณจะไม่ได้รับสายโทรเข้า, SMS หรือการแจ้งเตือนจากแอปงาน" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 490ce0684a..b91d67e8be 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -81,7 +81,6 @@ "Binibigyang-daan ang app na basahin ang mga setting at shortcut sa home." "magsulat ng mga setting at shortcut ng home" "Binibigyang-daan ang app na baguhin ang mga setting at shortcut sa home." - "Hindi pinahihintulutang tumawag ang %1$s" "Hindi ma-load ang widget" "Mga setting ng widget" "I-tap para tapusin ang pag-set up" @@ -101,6 +100,7 @@ "Folder: %1$s, %2$d o higit pang item" "Mga Wallpaper" "Wallpaper & istilo" + "I-edit ang Home Screen" "Mga setting ng Home" "Na-disable ng iyong admin" "Payagan ang pag-rotate ng home screen" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 4b2f6dac1b..d439162ad0 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -81,7 +81,6 @@ "Uygulamaya ana ekrandaki ayarları ve kısayolları okuma izni verir." "ana ekran ayarlarını ve kısayollarını yaz" "Uygulamaya ana ekrandaki ayarları ve kısayolları değiştirme izni verir." - "%1$s uygulamasının telefon etmesine izin verilmiyor" "Widget yüklenemiyor" "Widget ayarları" "Kurulumu tamamlamak için dokunun" @@ -101,6 +100,7 @@ "Klasör: %1$s, %2$d veya daha fazla öğe" "Duvar Kağıtları" "Duvar kağıdı ve stil" + "Ana ekranı düzenleyin" "Ana ekran ayarları" "Yöneticiniz tarafından devre dışı bırakıldı" "Ana ekranı döndürmeye izin ver" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index c8d29f4666..dcf60a90b5 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -81,7 +81,6 @@ "Дозволяє додатку читати налаштування та ярлики на головному екрані." "записувати налаштування та ярлики головного екрана" "Дозволяє додатку змінювати налаштування та ярлики на головному екрані." - "Додаток %1$s не має дозволу телефонувати" "Не вдається завантажити віджет" "Налаштування віджета" "Торкніться, щоб завершити налаштування" @@ -101,6 +100,7 @@ "Папка \"%1$s\", елементів: %2$d або більше" "Фонові малюнки" "Оформлення і стиль" + "Редагувати головний екран" "Налаштування головного екрана" "Вимкнув адміністратор" "Дозволити обертання головного екрана" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 7016491db1..5b10dd21ee 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -81,7 +81,6 @@ "اس سے ایپ کو ہوم اسکرین میں ترتیبات اور شارٹ کٹس کو پڑھنے کی اجازت ملتی ہے۔" "ہوم ترتیبات اور شارٹ کٹس کو لکھیں" "اس سے ایپ کو ہوم اسکرین میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت ملتی ہے۔" - "%1$s کو فون کالیں کرنے کی اجازت نہیں ہے" "ویجیٹ لوڈ نہیں کیا جا سکتا" "ویجیٹ کی ترتیبات" "سیٹ اپ مکمل کرنے کیلئے تھپتھپائیں" @@ -101,6 +100,7 @@ "فولڈر: %1$s، %2$d یا مزید آئٹمز" "وال پیپرز" "وال پیپر اور طرز" + "ہوم اسکرین میں ترمیم کریں" "ہوم ترتیبات" "آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا" "ہوم اسکرین گھمانے کی اجازت دیں" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index efee72365f..81ad4dce90 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -81,7 +81,6 @@ "Ilovaga bosh ekrandagi yorliqlar va sozlamalarni oʻqish uchun ruxsat beradi." "Bosh ekrandagi sozlamalar va yorliqlarni oʻzgartirish" "Ilova bosh ekrandagi yorliqlar va sozlamalarni oʻzgartirishi mumkin." - "%1$s ilovasiga qo‘ng‘iroqlarni amalga oshirishga ruxsat berilmagan" "Vidjet yuklanmadi" "Vidjet sozlamalari" "Sozlashni yakunlash uchun bosing" @@ -101,6 +100,7 @@ "Jild: %1$s, %2$d va undan ortiq fayllar" "Fon rasmlari" "Fon rasmi va uslubi" + "Bosh ekranni tahrirlash" "Bosh ekran sozlamalari" "Administrator tomonidan o‘chirilgan" "Bosh ekranni burishga ruxsat" diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml index 054fe47125..985fe77f62 100644 --- a/res/values-v31/colors.xml +++ b/res/values-v31/colors.xml @@ -64,5 +64,28 @@ @android:color/system_neutral2_700 - @android:color/system_accent2_100 + + @android:color/system_neutral1_900 + + @android:color/system_neutral1_900 + + @android:color/system_neutral2_700 + + @android:color/system_accent2_100 + + @android:color/system_accent1_0 + + @android:color/system_accent1_600 + + @android:color/system_neutral2_700 + + @android:color/system_accent1_600 + + @android:color/system_neutral1_100 + + @android:color/system_accent1_0 + + @android:color/system_neutral2_700 + + @android:color/system_neutral2_200 diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml index 008a77c3a8..932ce38e59 100644 --- a/res/values-v31/styles.xml +++ b/res/values-v31/styles.xml @@ -24,7 +24,7 @@ 24dp @android:color/transparent @android:color/transparent - @style/HomeSettings.SwitchStyle + @style/SwitchStyle @style/HomeSettings.PreferenceTitle false true @@ -61,13 +61,6 @@ @bool/home_settings_icon_space_reserved - - + +