diff options
162 files changed, 2630 insertions, 2335 deletions
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index dd1446635..ad404c09a 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -82,13 +82,15 @@ <service android:name="com.android.launcher3.dynamicui.ColorExtractionService" android:exported="false" - android:process=":wallpaper_chooser"> + android:process=":wallpaper_chooser" + android:permission="android.permission.BIND_JOB_SERVICE"> </service> <service android:name="com.android.launcher3.compat.WallpaperManagerCompatVL$ColorExtractionService" android:exported="false" - android:process=":wallpaper_chooser" /> + android:process=":wallpaper_chooser" + android:permission="android.permission.BIND_JOB_SERVICE" /> <service android:name="com.android.launcher3.notification.NotificationListener" android:enabled="@bool/notification_badging_enabled" diff --git a/res/layout/qsb_blocker_view.xml b/res/color-v24/all_apps_bg_hand_fill.xml index 453eebe4f..1b0b53890 100644 --- a/res/layout/qsb_blocker_view.xml +++ b/res/color-v24/all_apps_bg_hand_fill.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project +<!-- Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. --> -<com.android.launcher3.qsb.QsbBlockerView +<gradient xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" />
\ No newline at end of file + android:startX="158.5" + android:startY="141.5" + android:endX="196.0" + android:endY="206.5" + android:type="linear" > + <item android:offset="0" android:color="#E1E1E1" /> + <item android:offset="0.3317" android:color="#E1E1E1" /> + <item android:offset="0.493" android:color="#C1E5E5E5" /> + <item android:offset="1" android:color="#00EEEEEE" /> +</gradient>
\ No newline at end of file diff --git a/res/drawable-hdpi/ic_all_apps_bg_hand.png b/res/drawable-hdpi/ic_all_apps_bg_hand.png Binary files differdeleted file mode 100644 index 437fd374c..000000000 --- a/res/drawable-hdpi/ic_all_apps_bg_hand.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_all_apps_bg_hand.png b/res/drawable-mdpi/ic_all_apps_bg_hand.png Binary files differdeleted file mode 100644 index 0a0024138..000000000 --- a/res/drawable-mdpi/ic_all_apps_bg_hand.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_all_apps_bg_hand.png b/res/drawable-xhdpi/ic_all_apps_bg_hand.png Binary files differdeleted file mode 100644 index 1acb378ba..000000000 --- a/res/drawable-xhdpi/ic_all_apps_bg_hand.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_all_apps_bg_hand.png b/res/drawable-xxhdpi/ic_all_apps_bg_hand.png Binary files differdeleted file mode 100644 index 09c6c8d52..000000000 --- a/res/drawable-xxhdpi/ic_all_apps_bg_hand.png +++ /dev/null diff --git a/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png b/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png Binary files differdeleted file mode 100644 index 49c004dba..000000000 --- a/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png +++ /dev/null diff --git a/res/drawable/ic_all_apps_bg_hand.xml b/res/drawable/ic_all_apps_bg_hand.xml new file mode 100644 index 000000000..94af00870 --- /dev/null +++ b/res/drawable/ic_all_apps_bg_hand.xml @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:width="208dp" + android:height="212dp" + android:viewportWidth="208.0" + android:viewportHeight="212.0"> + <path + android:fillColor="#1A000000" + android:pathData="M89.4,61.8H85l-1.6-1.5c5.5-6.4,8.8-14.7,8.8-23.7C92.2,16.6,76,0.3,55.9,0.3 + S19.5,16.6,19.5,36.6S35.8,73,55.9,73c9,0,17.3-3.3,23.7-8.8l1.5,1.6v4.4l40.5,40.4l8.3-8.3L89.4,61.8z M54,66.6 + c-13.9,0-28.8-16-28.8-30S41.5,8.9,55.4,8.9S81,22.7,81,36.6S67.9,66.6,54,66.6z"/> + <path + android:fillColor="#1A000000" + android:pathData="M33.4,29.2l-0.3-1.8l-4.2-3.1L18.1,26l-3.1,4.2l0.3,1.8L4.5,33.7L9,62.5 + c0.2,1.5,1.6,2.5,3.1,2.3l34.2-5.3c1.5-0.2,2.5-1.6,2.3-3.1l-4.4-28.8L33.4,29.2z"/> + <path + android:fillColor="#3367D6" + android:pathData="M30.2,27.9l-0.3-1.8l-4.1-3L15,24.7l-3,4.1l0.3,1.8L1.6,32.3L6,60.9 + c0.2,1.5,1.6,2.5,3.1,2.3L43,57.9c1.5-0.2,2.5-1.6,2.3-3.1l-4.4-28.6L30.2,27.9z M26.6,28.4l-10.7,1.6l-0.3-1.8l10.7-1.6L26.6,28.4z"/> + <group> + <clip-path + android:pathData="M25.1,37.7a28.9,28.9 0 1,0 57.8,0a28.9,28.9 0 1,0 -57.8,0"/> + <path + android:fillColor="#4285F4" + android:pathData="M41.7,23l-0.3-2.1l-4.9-3.6l-12.6,1.9l-3.6,4.9l0.3,2.1L8.1,28.1l5.2,33.7 + c0.3,1.7,1.9,2.9,3.6,2.7l40-6.1c1.7-0.3,2.9-1.9,2.7-3.6L54.4,21L41.7,23z M37.5,23.6l-12.6,1.9l-0.3-2.1l12.6-1.9L37.5,23.6z"/> + </group> + <path + android:fillColor="#BDBDBD" + android:pathData="M87.5,62.9h-4.4l-1.6-1.5c5.5-6.4,8.8-14.7,8.8-23.7C90.3,17.7,74,1.4,54,1.4 + S17.6,17.7,17.6,37.7S33.9,74.1,54,74.1c9,0,17.3-3.3,23.7-8.8l1.5,1.6v4.4l40.5,40.4l8.3-8.3L87.5,62.9z M54,64.2 + c-14.7,0-26.5-11.8-26.5-26.5S39.3,11.2,54,11.2s26.5,11.8,26.5,26.5S68.6,64.2,54,64.2z"/> + <path + android:fillColor="#1A000000" + android:pathData="M153.4,112.9c-14.9-17.2-38.6-9.1-38.6-9.1l-10.2-11.3c0,0-4.8-5.9-9-3.7 + c-7,3.6-0.6,10.7-0.6,10.7s12.3,15.1,15.4,20.1c2.1,3.4,8.4,4.5,10.1,4.9l17.1,3.7l-0.9-0.7l-1-0.7L153.4,112.9z"/> + <path + android:fillColor="#FFDBA6" + android:pathData="M152.1,113.9c-14.9-17.2-37.6-8-37.6-8l-11.1-12.3c0,0-4.8-5.9-9-3.7 + c-7,3.6-0.6,10.7-0.6,10.7s12.3,15.1,15.4,20.1c2.1,3.4,8.4,4.5,10.1,4.9l19,4.1"/> + <path + android:fillColor="#1A000000" + android:pathData="M148.6,77.9c0.6,0.7,2,2.5,2.1,2.6c1.1,1.7,6.2,13.6,11.8,35.1c0,0.1,1.9,3,1.9,3.1 + c0,0,0.1,0.1,0.1,0.2c0,0,0,0,0-0.1c0.9,1.3,4.4,6.6,8.9,13.7c0.1,0.2,0.3,0.5,0.4,0.7c0,0.1,0.1,0.1,0.1,0.2 + c0.2,0.3,0.4,0.6,0.6,0.9c0.1-0.1,0.2-0.2,0.3-0.3c0.2-0.3,0.6-0.3,0.8,0c2.9,4.8,21.2,35,26.7,49c2.1,5.3,3.2,8.4,3.6,11.6 + c0.3,2.3,0,4.4-1.2,6c1.5-1.9,3.5-6.8-1.5-19c-1.2-2.9-2.8-6.5-4.8-10.5c-7.5-15.2-20-35.6-22.4-39.6c-0.2-0.3-0.6-0.3-0.8,0 + c-0.2,0.2-0.3,0.4-0.5,0.6c-4.5-7.1-8.2-12.6-8.8-13.5c-0.1-0.1-1.9-3-1.9-3.1c-5.7-21.6-10.7-33.4-11.8-35.1 + c-0.1-0.1-1.5-1.9-2.1-2.6l-6.5-8.3c-1.9-2.3-4.2-4.1-6.7-2.3c-2.5,1.8-1.6,4.5-0.1,7.1l3.3,5.2l7-2 + C147.7,77.4,148.1,77.3,148.6,77.9z"/> + <path + android:fillColor="#FFDBA6" + android:pathData="M148.6,77.9l-6.5-8.3c-1.9-2.3-4.2-4.1-6.7-2.3l0,0l0,0c-2.5,1.8-1.6,4.5-0.1,7.1l3.8,6L148.6,77.9C148.6,77.9,148.6,77.9,148.6,77.9z"/> + <path + android:fillColor="#1A000000" + android:pathData="M151.1,92.5l-19.7-25.3c-1.9-2.3-4.2-4.1-6.7-2.3l0,0l0,0c-2.5,1.8-1.6,4.5-0.1,7.1l17.1,27.2L151.1,92.5z"/> + <path + android:fillColor="#FFDBA6" + android:pathData="M149.7,92.9l-19.7-25.3c-1.9-2.3-4.2-4.1-6.7-2.3l0,0l0,0c-2.5,1.8-1.6,4.5-0.1,7.1l17.1,27.2L149.7,92.9z"/> + <path + android:fillColor="#1A000000" + android:pathData="M141.6,94.6l-20.8-26.7c-2.1-2.5-4.4-4.3-7.1-2.5l0,0l0,0c-2.6,1.9-1.7,4.7-0.1,7.5l18,28.6L141.6,94.6z"/> + <path + android:fillColor="#FFDBA6" + android:pathData="M140.1,95l-20.8-26.7c-2.1-2.5-4.4-4.3-7.1-2.5l0,0h0c-2.6,1.9-1.7,4.7-0.1,7.5l18,28.6L140.1,95z"/> + <path + android:fillColor="#1A000000" + android:pathData="M140.4,99.1c-0.5-0.6-2.1-7.5-2.8-7.3l-15.9-6.9c-0.3,0-0.5-0.1-0.7-0.3l-2.3-3.5 + l-0.4-0.6L100,54.5c-1.5-2-3.3-4-5.3-4.3c-0.7-0.1-1.3-0.2-2,0.2v0c-1,0.6-1.2,1.5-1.3,2.4c-0.2,1.8,0.6,3.9,1.6,5.9L108.5,87 + l0.2,0.4l6.6,11.7l0,0c2.5,4.5,4.4,10.5,4.4,10.7L140.4,99.1"/> + <path + android:fillColor="#FFDBA6" + android:pathData="M129.7,125.1c3,0.7,8.1,4,11.8,9.1c2.7,3.7,5.5,8.3,8.2,13 + c7.6-2.3,19.9-6.8,24.9-12.9c-0.2-0.3-0.4-0.6-0.6-0.9c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.2-0.3-0.5-0.4-0.7c-4.5-7.1-8-12.4-8.9-13.7 + c0,0,0,0,0,0.1c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.1-1.9-3-1.9-3.1c-5.7-21.5-10.7-33.4-11.8-35.1c-0.1-0.1-1.5-1.9-2.1-2.6 + c-0.5-0.6-0.9-0.5-1.6-0.3l-26.8,7.7c-0.3,0-0.5-0.1-0.7-0.3l-2.3-3.5l-0.4-0.6L98.5,54.8c-1.5-2-3.3-4-5.3-4.3 + c-0.7-0.1-1.3-0.2-2,0.2c-1,0.6-1.2,1.5-1.3,2.4c-0.2,1.8,0.6,3.9,1.6,5.9L107,87.3l0.2,0.4l6.6,11.7l0,0 + c2.5,4.5,4.4,10.5,4.4,10.7L129.7,125.1"/> + <path + android:fillColor="@color/all_apps_bg_hand_fill" + android:pathData="M202.3,183.1c-5.4-14.1-23.8-44.3-26.7-49c-0.2-0.3-0.6-0.3-0.8,0 + c-5.1,6.6-19,11.4-26.5,13.6c-0.3,0.1-1,0.1-1.2,0.6c-0.2,0.4,0.1,1,0.2,1.1c7.8,12.9,14.7,27.9,15.3,29.3c0,0.1,0.1,0.1,0.1,0.2 + l9.6,22.9c0,0,0,0,0,0l1.7,4.1c1.4,2.7,3,4.3,5.3,5.1c1.5,0.5,2.1,0.6,3.2,0.6c4.8,0.1,15.2-6.1,20.5-9.4c2.7-1.7,3.3-4.4,2.9-7.6 + C205.5,191.5,204.4,188.4,202.3,183.1z"/> +</vector>
\ No newline at end of file diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index 1e82f2276..2e0357672 100644 --- a/res/layout-land/launcher.xml +++ b/res/layout-land/launcher.xml @@ -27,7 +27,7 @@ android:id="@+id/drag_layer" android:clipChildren="false" android:clipToPadding="false" - android:background="@drawable/workspace_bg" + android:background="?attr/workspaceStatusBarScrim" android:importantForAccessibility="no" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -67,12 +67,6 @@ android:layout_height="@dimen/dynamic_grid_page_indicator_height" android:layout_gravity="bottom|left"/> - <!-- A place holder view instead of the QSB in transposed layout --> - <View - android:layout_width="0dp" - android:layout_height="10dp" - android:id="@+id/workspace_blocked_row" /> - <include layout="@layout/widgets_view" android:id="@+id/widgets_view" android:layout_width="match_parent" diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml index c15e53d8d..93c90780b 100644 --- a/res/layout-port/launcher.xml +++ b/res/layout-port/launcher.xml @@ -29,7 +29,7 @@ android:clipChildren="false" android:importantForAccessibility="no" android:clipToPadding="false" - android:background="@drawable/workspace_bg" + android:background="?attr/workspaceStatusBarScrim" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -66,10 +66,6 @@ android:id="@+id/drop_target_bar" layout="@layout/drop_target_bar_horz" /> - <include - layout="@layout/qsb_container" - android:id="@+id/qsb_container" /> - <include layout="@layout/widgets_view" android:id="@+id/widgets_view" android:layout_width="match_parent" diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml index c516c4697..ca4d846f1 100644 --- a/res/layout-sw720dp/launcher.xml +++ b/res/layout-sw720dp/launcher.xml @@ -28,7 +28,7 @@ android:clipChildren="false" android:clipToPadding="false" android:importantForAccessibility="no" - android:background="@drawable/workspace_bg" + android:background="?attr/workspaceStatusBarScrim" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -65,10 +65,6 @@ <include layout="@layout/page_indicator" android:id="@+id/page_indicator" /> - <include - layout="@layout/qsb_container" - android:id="@+id/qsb_container" /> - <include layout="@layout/widgets_view" android:id="@+id/widgets_view" android:layout_width="match_parent" diff --git a/res/layout/app_widget_resize_frame.xml b/res/layout/app_widget_resize_frame.xml index 91a1e45a0..874fecccf 100644 --- a/res/layout/app_widget_resize_frame.xml +++ b/res/layout/app_widget_resize_frame.xml @@ -20,38 +20,43 @@ android:layout_height="match_parent" android:background="@drawable/widget_resize_shadow" android:foreground="@drawable/widget_resize_frame" + android:foregroundTint="?attr/workspaceTextColor" android:padding="0dp" > <!-- Left --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/ic_widget_resize_handle" android:layout_gravity="left|center_vertical" - android:layout_marginLeft="@dimen/widget_handle_margin" /> + android:layout_marginLeft="@dimen/widget_handle_margin" + android:src="@drawable/ic_widget_resize_handle" + android:tint="?attr/workspaceTextColor" /> <!-- Top --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/ic_widget_resize_handle" android:layout_gravity="top|center_horizontal" - android:layout_marginTop="@dimen/widget_handle_margin" /> + android:layout_marginTop="@dimen/widget_handle_margin" + android:src="@drawable/ic_widget_resize_handle" + android:tint="?attr/workspaceTextColor" /> <!-- Right --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/ic_widget_resize_handle" android:layout_gravity="right|center_vertical" - android:layout_marginRight="@dimen/widget_handle_margin" /> + android:layout_marginRight="@dimen/widget_handle_margin" + android:src="@drawable/ic_widget_resize_handle" + android:tint="?attr/workspaceTextColor" /> <!-- Bottom --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/ic_widget_resize_handle" android:layout_gravity="bottom|center_horizontal" - android:layout_marginBottom="@dimen/widget_handle_margin" /> + android:layout_marginBottom="@dimen/widget_handle_margin" + android:src="@drawable/ic_widget_resize_handle" + android:tint="?attr/workspaceTextColor" /> </com.android.launcher3.AppWidgetResizeFrame>
\ No newline at end of file diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml index 85caba4a0..4a2ad4225 100644 --- a/res/layout/deep_shortcut.xml +++ b/res/layout/deep_shortcut.xml @@ -18,7 +18,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" - android:layout_height="@dimen/bg_popup_item_height" > + android:layout_height="@dimen/bg_popup_item_height" + android:theme="@style/PopupItem" > <com.android.launcher3.shortcuts.DeepShortcutTextView style="@style/BaseIcon" @@ -50,6 +51,6 @@ android:layout_height="@dimen/popup_item_divider_height" android:layout_gravity="end|bottom" android:visibility="gone" - android:background="?android:attr/listDivider" /> + android:background="?attr/popupColorTertiary" /> </com.android.launcher3.shortcuts.DeepShortcutView> diff --git a/res/layout/drop_target_bar_vert.xml b/res/layout/drop_target_bar_vert.xml index e2a65d4a5..2394d0d13 100644 --- a/res/layout/drop_target_bar_vert.xml +++ b/res/layout/drop_target_bar_vert.xml @@ -32,8 +32,7 @@ android:gravity="center" android:paddingLeft="@dimen/vert_drop_target_horizontal_gap" android:paddingRight="@dimen/vert_drop_target_horizontal_gap" - android:id="@+id/delete_target_text" - android:textColor="@android:color/white" /> + android:id="@+id/delete_target_text" /> <!-- Uninstall target --> <com.android.launcher3.UninstallDropTarget @@ -43,7 +42,6 @@ android:paddingLeft="@dimen/vert_drop_target_horizontal_gap" android:paddingRight="@dimen/vert_drop_target_horizontal_gap" android:id="@+id/uninstall_target_text" - android:textColor="@android:color/white" android:layout_marginTop="@dimen/vert_drop_target_vertical_gap"/> <Space @@ -59,7 +57,6 @@ android:paddingLeft="@dimen/vert_drop_target_horizontal_gap" android:paddingRight="@dimen/vert_drop_target_horizontal_gap" android:id="@+id/info_target_text" - android:textColor="@android:color/white" android:layout_marginBottom="64dp"/> </com.android.launcher3.DropTargetBar>
\ No newline at end of file diff --git a/res/layout/horizontal_divider.xml b/res/layout/horizontal_divider.xml index 33773ebfa..167f8f5d8 100644 --- a/res/layout/horizontal_divider.xml +++ b/res/layout/horizontal_divider.xml @@ -2,4 +2,4 @@ <View xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="@dimen/popup_item_divider_height" - android:background="?android:attr/listDivider"/>
\ No newline at end of file + android:background="?attr/popupColorTertiary" />
\ No newline at end of file diff --git a/res/layout/notification.xml b/res/layout/notification.xml index a03dd0833..085dfa93c 100644 --- a/res/layout/notification.xml +++ b/res/layout/notification.xml @@ -19,6 +19,7 @@ android:id="@+id/notification_view" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="wrap_content" + android:theme="@style/PopupItem" android:elevation="@dimen/deep_shortcuts_elevation"> <RelativeLayout @@ -33,7 +34,7 @@ android:layout_height="@dimen/notification_header_height" android:paddingStart="@dimen/notification_padding_start" android:paddingEnd="@dimen/notification_padding_end" - android:background="@color/popup_background_color" + android:background="?attr/popupColorPrimary" android:elevation="@dimen/notification_elevation"> <TextView android:id="@+id/notification_text" @@ -65,8 +66,9 @@ android:id="@+id/divider" android:layout_width="match_parent" android:layout_height="@dimen/popup_item_divider_height" - android:background="?android:attr/listDivider" - android:layout_below="@id/main_view"/> + android:background="?attr/popupColorTertiary" + android:layout_below="@id/main_view" + android:visibility="gone" /> <include layout="@layout/notification_footer" android:id="@+id/footer" diff --git a/res/layout/notification_footer.xml b/res/layout/notification_footer.xml index ed2212be1..86280e0b6 100644 --- a/res/layout/notification_footer.xml +++ b/res/layout/notification_footer.xml @@ -22,7 +22,7 @@ android:elevation="@dimen/notification_elevation" android:clipChildren="false" android:layout_gravity="center_vertical" - android:background="@color/popup_background_color"> + android:background="?attr/popupColorPrimary"> <LinearLayout android:id="@+id/icon_row" diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml index ce4e137f7..b2443f5d9 100644 --- a/res/layout/notification_main.xml +++ b/res/layout/notification_main.xml @@ -28,7 +28,7 @@ android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_vertical" - android:background="@color/popup_background_color" + android:background="?attr/popupColorPrimary" android:paddingStart="@dimen/notification_padding_start" android:paddingEnd="@dimen/notification_main_text_padding_end"> <TextView diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml index 78a0f1596..d1ac56c50 100644 --- a/res/layout/overview_panel.xml +++ b/res/layout/overview_panel.xml @@ -32,12 +32,13 @@ android:layout_weight="1" android:drawablePadding="4dp" android:drawableTop="@drawable/ic_wallpaper" + android:drawableTint="?attr/workspaceTextColor" android:fontFamily="sans-serif-condensed" android:gravity="center_horizontal" android:stateListAnimator="@animator/overview_button_anim" android:text="@string/wallpaper_button_text" android:textAllCaps="true" - android:textColor="@android:color/white" + android:textColor="?attr/workspaceTextColor" android:textSize="12sp" /> <TextView @@ -47,12 +48,13 @@ android:layout_weight="1" android:drawablePadding="4dp" android:drawableTop="@drawable/ic_widget" + android:drawableTint="?attr/workspaceTextColor" android:fontFamily="sans-serif-condensed" android:gravity="center_horizontal" android:stateListAnimator="@animator/overview_button_anim" android:text="@string/widget_button_text" android:textAllCaps="true" - android:textColor="@android:color/white" + android:textColor="?attr/workspaceTextColor" android:textSize="12sp" /> <TextView @@ -62,12 +64,13 @@ android:layout_weight="1" android:drawablePadding="4dp" android:drawableTop="@drawable/ic_setting" + android:drawableTint="?attr/workspaceTextColor" android:fontFamily="sans-serif-condensed" android:gravity="center_horizontal" android:stateListAnimator="@animator/overview_button_anim" android:text="@string/settings_button_text" android:textAllCaps="true" - android:textColor="@android:color/white" + android:textColor="?attr/workspaceTextColor" android:textSize="12sp" /> </LinearLayout>
\ No newline at end of file diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml index 6f702f62b..04f3d027d 100644 --- a/res/layout/system_shortcut.xml +++ b/res/layout/system_shortcut.xml @@ -15,11 +15,11 @@ --> <com.android.launcher3.shortcuts.DeepShortcutView - android:theme="@style/IconWithTextSystemShortcut" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" - android:layout_height="@dimen/bg_popup_item_height" > + android:layout_height="@dimen/bg_popup_item_height" + android:theme="@style/PopupItem" > <com.android.launcher3.BubbleTextView style="@style/BaseIcon" @@ -41,7 +41,8 @@ android:layout_width="@dimen/system_shortcut_icon_size" android:layout_height="@dimen/system_shortcut_icon_size" android:layout_marginStart="@dimen/system_shortcut_margin_start" - android:layout_gravity="start|center_vertical" /> + android:layout_gravity="start|center_vertical" + android:backgroundTint="?android:attr/textColorTertiary"/> <View android:id="@+id/divider" @@ -49,6 +50,6 @@ android:layout_height="@dimen/popup_item_divider_height" android:layout_gravity="end|bottom" android:visibility="gone" - android:background="?android:attr/listDivider" /> + android:background="?attr/popupColorTertiary" /> </com.android.launcher3.shortcuts.DeepShortcutView> diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml index 2b58b92ee..c59cb5331 100644 --- a/res/layout/system_shortcut_icon_only.xml +++ b/res/layout/system_shortcut_icon_only.xml @@ -16,8 +16,9 @@ <ImageView xmlns:android="http://schemas.android.com/apk/res/android" - android:theme="@style/IconOnlySystemShortcut" android:layout_width="@dimen/system_shortcut_header_icon_touch_size" android:layout_height="@dimen/system_shortcut_header_icon_touch_size" android:background="?android:attr/selectableItemBackgroundBorderless" - android:padding="@dimen/system_shortcut_header_icon_padding" /> + android:tint="?android:attr/textColorHint" + android:padding="@dimen/system_shortcut_header_icon_padding" + android:theme="@style/PopupItem" /> diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml index 676be8e69..db59d4962 100644 --- a/res/layout/system_shortcut_icons.xml +++ b/res/layout/system_shortcut_icons.xml @@ -21,4 +21,4 @@ android:layout_height="@dimen/system_shortcut_header_height" android:orientation="horizontal" android:gravity="end|center_vertical" - android:background="@color/popup_header_background_color" /> + android:background="?attr/popupColorSecondary" /> diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml index c2270d212..f1370f0c4 100644 --- a/res/layout/widgets_bottom_sheet.xml +++ b/res/layout/widgets_bottom_sheet.xml @@ -25,11 +25,11 @@ android:layout_gravity="bottom"> <TextView + style="@style/TextTitle" android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:fontFamily="sans-serif" android:textColor="?android:attr/textColorPrimary" android:textSize="24sp"/> diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index fda7db19c..68b830779 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Gebruik stelselverstek"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Vierkant"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Sirkelvierkant"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Sirkel"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Traandruppel"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string> diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 285237663..cb2634d27 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"استخدام الإعداد الافتراضي للنظام"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"مربّع"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"رمز دائري مربّع"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"دائرة"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"رمز على شكل دمعة"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"غير معروفة"</string> diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml index 6b997883f..1f89f5a22 100644 --- a/res/values-az-rAZ/strings.xml +++ b/res/values-az-rAZ/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Sistem defoltu istifadə edin"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kənarları dairəvi kvadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Çevrə"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Gözyaşı damlası"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Naməlum"</string> diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index d96bd62f7..9f2855d4d 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Koristi podrazumevano sistemsko podešavanje"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljeni kvadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Krug"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Suza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string> diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml index 8ee166323..a0b7a6927 100644 --- a/res/values-be-rBY/strings.xml +++ b/res/values-be-rBY/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Выкарыстоўваць стандартныя формы"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Прамавугольнік са скругленымі вугламі"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Сляза"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Невядома"</string> diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 61de76f24..fc3ba4ba8 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Използване на стандартната системна настройка"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Комбинация от кръг и квадрат"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Кръг"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Сълза"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Няма информация"</string> diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml index d7bd83b7f..1ee4b6b17 100644 --- a/res/values-bn-rBD/strings.xml +++ b/res/values-bn-rBD/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"আইকনের আকৃতি পরিবর্তন করুন"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"সিস্টেমের ডিফল্ট মান ব্যবহার করুন"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"চৌকো"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"চৌকো-গোলাকার"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"গোলাকার"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"চোখের জল"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"আইকনের আকৃতি পরিবর্তন করা হচ্ছে"</string> <string name="package_state_unknown" msgid="7592128424511031410">"অজানা"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"সরান"</string> diff --git a/res/values-bs-rBA/strings.xml b/res/values-bs-rBA/strings.xml index c14841383..259e51617 100644 --- a/res/values-bs-rBA/strings.xml +++ b/res/values-bs-rBA/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Koristite sistemski zadano"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljeni kvadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Krug"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Suza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string> diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 245c76017..feee97d40 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Utilitza l\'opció predeterminada del sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Quadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrat arrodonit"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cercle"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Llàgrima"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Desconegut"</string> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 556294b56..2560de3d5 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Použít výchozí nastavení systému"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Čtverec"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kruh/čtverec"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Kruh"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Slza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Neznámé"</string> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index f811f119c..521f9eab1 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Brug systemstandarden"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadrat med runde hjørner"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cirkel"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Dråbeform"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Ukendt"</string> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index f25b46fc4..03eb04801 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Systemstandardeinstellung verwenden"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Quadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Superkreis"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Kreis"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Träne"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Unbekannt"</string> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index a148c51ce..a2b44b4bc 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Χρήση προεπιλογής συστήματος"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Τετράγωνο"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Στρογγυλεμένο τετράγωνο"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Κύκλος"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Δάκρυ"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Άγνωστο"</string> diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 504bd81cb..08ef4f4e3 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Square"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Circle"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string> diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 504bd81cb..08ef4f4e3 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Square"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Circle"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string> diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 504bd81cb..08ef4f4e3 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Square"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Circle"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 499927565..e4315bba1 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar el sistema predeterminado"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Cuadrado"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Cuadrado con esquinas redondeadas"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Gota"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 5e4f1617d..3c2691067 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar opción predeterminada del sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Cuadrado"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Cuadrado con esquinas redondeadas"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lágrima"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string> diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml index 51a3f7ab3..3cd9a9ea4 100644 --- a/res/values-et-rEE/strings.xml +++ b/res/values-et-rEE/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Kasuta süsteemi vaikeseadet"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Ruut"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Ümarate nurkadega ruut"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Ring"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Tilk"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Teadmata"</string> diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml index 063ce2b6a..dfb969f36 100644 --- a/res/values-eu-rES/strings.xml +++ b/res/values-eu-rES/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Erabili sistemaren balio lehenetsiak"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Karratua"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Ertz biribilduko karratua"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Zirkulua"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Malkoa"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Ezezaguna"</string> diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index f3b3a8477..7da80a400 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"استفاده از پیشفرض سیستم"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"مربع"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"مربع با گوشههای گرد"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"دایره"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"قطره اشک"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"نامشخص"</string> diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 49d44f85d..b125d4514 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Käytä järjestelmän oletusarvoa"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Neliö"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Ympyräneliö"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Ympyrä"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Pisara"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Tuntematon"</string> diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 0169e5dbd..3b7a1aebd 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Utiliser les valeurs système par défaut"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Carré"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Carré aux coins ronds"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cercle"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Goutte"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 944a6cb4c..ca4c7e7ea 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Utiliser la valeur système par défaut"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Carré"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cercle"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Goutte"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string> diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml index fb4489c64..c1d2536ce 100644 --- a/res/values-gl-rES/strings.xml +++ b/res/values-gl-rES/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar valores predeterminados do sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Cadrado"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Cadrado de bordos redondeados"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Bágoa"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Descoñecido"</string> diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml index 9a316b296..31d92b016 100644 --- a/res/values-gu-rIN/strings.xml +++ b/res/values-gu-rIN/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"આઇકનનો આકાર બદલો"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"સિસ્ટમ ડિફૉલ્ટનો ઉપયોગ કરો"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ચોરસ"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ચોરસ જેવું ગોળ"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"વર્તુળ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"ટિઅરડ્રોપ"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"આઇકનના આકારમાં કરેલ ફેરફારો લાગુ કરી રહ્યા છીએ"</string> <string name="package_state_unknown" msgid="7592128424511031410">"અજાણ્યો"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"દૂર કરો"</string> diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index db4a52e96..e5b316c6a 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"सिस्टम डिफ़ॉल्ट का उपयोग करें"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"वर्ग"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"गोल कोनों वाला वर्ग"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"मंडली"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"आंसू की बूंद"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string> diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 322fb3f58..de5f9aea0 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Upotrijebi zadane postavke sustava"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljeni kvadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Krug"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Suza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string> diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 938ed3081..f0f597cd1 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Alapértelmezett érték használata"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Négyzet"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Kör"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Könnycsepp"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string> diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml index b00ed68db..f9fa33779 100644 --- a/res/values-hy-rAM/strings.xml +++ b/res/values-hy-rAM/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Օգտագործել համակարգի կանխադրված կարգավորումը"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Քառակուսի"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Քառանկյուն"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Օղակ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Արցունքաձև"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string> diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 0c80fb7dd..3aff82bf3 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Gunakan default sistem"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Persegi"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Persegi bundar"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Lingkaran"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Butiran Air"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Tidak dikenal"</string> diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml index 702506599..b672245c2 100644 --- a/res/values-is-rIS/strings.xml +++ b/res/values-is-rIS/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Nota sjálfgildi kerfis"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Ferningur"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Ferhringur"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Hringur"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Dropi"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Óþekkt"</string> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index d0749cdc7..9e3fd93d1 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Usa impostazione predefinita di sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Quadrato"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Supercerchio"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cerchio"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Goccia"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Sconosciuto"</string> diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index b472fabb2..f02d15605 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"השתמש בברירת המחדל של המערכת"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ריבוע"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ריבוע בעל פינות מעוגלות"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"מעגל"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"טיפה"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"לא ידוע"</string> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 4a58056a5..dc6f9bc12 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"システムのデフォルトを使用"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"スクエア"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"スクワークル"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"サークル"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"ティアドロップ"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string> @@ -128,7 +124,7 @@ <string name="widget_resized" msgid="9130327887929620">"ウィジェットのサイズを幅<xliff:g id="NUMBER_0">%1$s</xliff:g>、高さ<xliff:g id="NUMBER_1">%2$s</xliff:g>に変更しました"</string> <string name="action_deep_shortcut" msgid="2864038805849372848">"ショートカット"</string> <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>用の <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 件のショートカット"</string> - <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 件のショートカットと <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> 件の通知"</string> + <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 個のショートカットと <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> 件の通知"</string> <string name="action_dismiss_notification" msgid="5909461085055959187">"表示しない"</string> <string name="notification_dismissed" msgid="6002233469409822874">"通知を非表示にしました"</string> </resources> diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml index 0bade8e41..5544ee152 100644 --- a/res/values-ka-rGE/strings.xml +++ b/res/values-ka-rGE/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"ნაგულისხმევი სისტემური პარამეტრების გამოყენება"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"კვადრატი"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"წრეკუთხედი"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"წრე"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"წვეთი"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string> diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml index 9b2dab321..1507a5899 100644 --- a/res/values-kk-rKZ/strings.xml +++ b/res/values-kk-rKZ/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Жүйенің әдепкі параметрін пайдалану"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Шаршы"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Жұмыр төртбұрыш"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Шеңбер"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Тамшы"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Белгісіз"</string> diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml index 59c13cc9c..9f0e72dfd 100644 --- a/res/values-km-rKH/strings.xml +++ b/res/values-km-rKH/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"ប្រើលំនាំដើមរបស់ប្រព័ន្ធ"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ការ៉េ"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ការ៉េជ្រុងកោង"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"រង្វង់"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"តំណក់ទឹកភ្នែក"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"មិនស្គាល់"</string> diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml index 1cda087cb..2785ad85a 100644 --- a/res/values-kn-rIN/strings.xml +++ b/res/values-kn-rIN/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ಚೌಕ"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ಚೌಕವೃತ್ತ"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"ವೃತ್ತ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"ಕಂಬನಿ"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"ಐಕಾನ್ ಆಕಾರ ಬದಲಾವಣೆಯನ್ನು ಅನ್ವಯಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="package_state_unknown" msgid="7592128424511031410">"ಅಪರಿಚಿತ"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"ತೆಗೆದುಹಾಕಿ"</string> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 2e8d149dc..f9185e86d 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"시스템 기본값 사용"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"정사각형"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"모서리가 둥근 정사각형"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"원"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"눈물방울"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"알 수 없음"</string> diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml index 791dfcb2a..87d98c5c7 100644 --- a/res/values-ky-rKG/strings.xml +++ b/res/values-ky-rKG/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Тутум сушунтаган демейкисин колдонуу"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Чарчы"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Бурчтары жумуру төрт бурчтук"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Тегерек"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Тамчы"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Белгисиз"</string> diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml index cbb17d92b..9530aef2b 100644 --- a/res/values-lo-rLA/strings.xml +++ b/res/values-lo-rLA/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"ໃຊ້ຄ່າເລີ່ມຕົ້ນລະບົບ"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ສີ່ຫຼ່ຽມຈັດຕຸລັດ"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ສີ່ຫຼ່ຽມຂອບມົນ"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"ວົງມົນ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"ນ້ຳຢອດ"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"ບໍ່ຮູ້ຈັກ"</string> diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 9c7f2aaf6..517e61137 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Naudoti numatytuosius sistemos nustatymus"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadratas"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadratais suapvalintais kampais"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Apskritimas"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Ašara"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Nežinoma"</string> diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index b7f426ee6..0c00bda9c 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Izmantot sistēmas noklusējumu"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrāts"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadrāts ar noapaļotiem stūriem"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Aplis"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lāse"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Nezināma"</string> diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml index 6d6473fa0..f9948922c 100644 --- a/res/values-mk-rMK/strings.xml +++ b/res/values-mk-rMK/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Користи ја стандардната поставка на системот"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Заоблен квадрат"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Солза"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string> diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml index b909c1108..5995c5cdc 100644 --- a/res/values-ml-rIN/strings.xml +++ b/res/values-ml-rIN/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"പുതിയ ആപ്പുകൾക്ക്"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"ഐക്കണിന്റെ ആകാരം മാറ്റുക"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"സിസ്റ്റം ഡിഫോൾട്ട് ഉപയോഗിക്കുക"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ചതുരം"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ചതുരവൃത്തം"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"വൃത്തം"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"കണ്ണുനീര് തുള്ളി"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"ഐക്കൺ ആകാര മാറ്റങ്ങൾ പ്രയോഗിക്കുന്നു"</string> <string name="package_state_unknown" msgid="7592128424511031410">"അജ്ഞാതം"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"നീക്കംചെയ്യുക"</string> diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml index 696b42ccf..11e795919 100644 --- a/res/values-mn-rMN/strings.xml +++ b/res/values-mn-rMN/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Системийн өгөгдмөл тохиргоог ашиглах"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Дөрвөлжин"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Мохоо өнцөгтэй дөрвөлжин"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Дугуй"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Дусал"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string> diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml index 0c74b1584..f9443a191 100644 --- a/res/values-mr-rIN/strings.xml +++ b/res/values-mr-rIN/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"चिन्हाचा आकार बदला"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"सिस्टमचे डीफॉल्ट वापरा"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"चौरस"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"गोलाकार चौरस"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"वर्तुळ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"अश्रू"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"चिन्हाचा आकार बदल लागू करत आहे"</string> <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"काढा"</string> diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml index 20410bce1..385a9438d 100644 --- a/res/values-ms-rMY/strings.xml +++ b/res/values-ms-rMY/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Gunakan lalai sistem"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Segi empat sama"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Segi empat berbucu bulat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Bulatan"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Titisan air mata"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Tidak diketahui"</string> diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml index 19e017e10..0588aaabf 100644 --- a/res/values-my-rMM/strings.xml +++ b/res/values-my-rMM/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"စနစ်၏ မူရင်းပုံကို အသုံးပြုရန်"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"လေးထောင့်"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"စတုရန်းမကျ စက်ဝိုင်းမကျပုံ"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"စက်ဝိုင်း"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"မျက်ရည်စက်ပုံ"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 4d3389e09..fb7eecdd5 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Bruk systemstandard"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Superellipse"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Sirkel"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Dråpe"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Ukjent"</string> diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml index 0f0c654d9..524e9c633 100644 --- a/res/values-ne-rNP/strings.xml +++ b/res/values-ne-rNP/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ अनुप्रयोगका लागि"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"आइकनको आकार परिवर्तन गर्नुहोस्"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"प्रणालीको पूर्वनिर्धारित सेटिङ प्रयोग गर्नुहोस्"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"वर्ग"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"वर्गाकार वृत्त"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"वृत्त"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"आँसुको थोपा"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"आइकनको आकारमा गरिएका परिवर्तनहरू लागू गरिँदैछन्"</string> <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"हटाउनुहोस्"</string> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 9e3556867..bd99a5c7b 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Systeemstandaard gebruiken"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Vierkant"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cirkel"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Traan"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string> diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml index 76c6bd537..97add38bb 100644 --- a/res/values-pa-rIN/strings.xml +++ b/res/values-pa-rIN/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"ਸਿਸਟਮ ਦੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈਟਿੰਗ ਵਰਤੋ"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"ਵਰਗ"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"ਵਰਗ ਰੂਪੀ ਗੋਲ-ਚੱਕਰ"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"ਗੋਲ-ਚੱਕਰ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"ਹੰਝੂ ਦੀ ਬੂੰਦ"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="package_state_unknown" msgid="7592128424511031410">"ਅਗਿਆਤ"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"ਹਟਾਓ"</string> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index b3eb42337..0955d13f5 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Użyj ustawienia domyślnego"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kwadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaokrąglony kwadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Okrąg"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Łza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Brak informacji"</string> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index d1b03aa35..e9e56cc84 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Utilizar a predefinição do sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Quadrado"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrado e círculo"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lágrima"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index c1176722f..4e178078d 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar padrão do sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Quadrado"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrado arredondado"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lágrima"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string> diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 69b44e28f..953b2c899 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Folosiți setarea prestabilită a sistemului"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Pătrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Pătrat cu colțuri rotunjite"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cerc"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lacrimă"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Necunoscut"</string> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 6f00f2d51..60296aeb6 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Использовать системные настройки по умолчанию"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Квадрат с закругленными краями"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Капля"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Неизвестно"</string> diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml index fec9ff8ab..ff6416f40 100644 --- a/res/values-si-rLK/strings.xml +++ b/res/values-si-rLK/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"පද්ධති පෙරනිමි භාවිත කරන්න"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"සමචතුරස්රය"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"හතරැස් කවය"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"කවය"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"කඳුළු බිංදුව"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"නොදනී"</string> diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 500f14f82..1a49d7d44 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Použiť predvolené nastavenie systému"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Štvorec"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Okrúhly štvorec"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Kruh"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Slza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Neznáme"</string> diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index bc951af46..16cb58cf9 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Uporabi privzeto nastavitev sistema"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljen kvadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Krog"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Solza"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Neznano"</string> diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml index f4798f6b7..1ad19ce28 100644 --- a/res/values-sq-rAL/strings.xml +++ b/res/values-sq-rAL/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Përdor parazgjedhjen e sisteit"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Katror"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Katror me kënde të rrumbullakëta"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Rreth"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Pikë loti"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"I panjohur"</string> diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index de24f3246..f02a829d3 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Користи подразумевано системско подешавање"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Заобљени квадрат"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Суза"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 0baf97d56..6778bdc83 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Använd systemstandard"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvirkel"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Cirkel"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Droppe"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Okänt"</string> diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 96a78db23..48e8a329f 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -86,14 +86,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Tumia umbo chaguo-msingi la mfumo"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Mraba"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Mstatili wenye pembe duara"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Mduara"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Umbo la chozi"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Yasiyojulikana"</string> diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml index bc65a0e9a..bb0dbc221 100644 --- a/res/values-sw720dp/styles.xml +++ b/res/values-sw720dp/styles.xml @@ -33,7 +33,6 @@ <style name="DropTargetButton" parent="DropTargetButtonBase"> <item name="android:paddingLeft">60dp</item> <item name="android:paddingRight">60dp</item> - <item name="android:shadowColor">#393939</item> <item name="android:shadowDx">0.0</item> <item name="android:shadowDy">0.0</item> <item name="android:shadowRadius">2.0</item> diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml index 15fb1106a..eca34ce9c 100644 --- a/res/values-ta-rIN/strings.xml +++ b/res/values-ta-rIN/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"அமைப்பின் இயல்புநிலையைப் பயன்படுத்து"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"சதுரம்"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"சதுரவட்டம்"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"வட்டம்"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"கண்ணீர்துளி"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"தெரியாதது"</string> diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml index 05c4788f4..e79512e23 100644 --- a/res/values-te-rIN/strings.xml +++ b/res/values-te-rIN/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"కొత్త అనువర్తనాల కోసం"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"చిహ్న ఆకారాన్ని మార్చు"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"సిస్టమ్ డిఫాల్ట్ను ఉపయోగించండి"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"చతురస్రం"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"చతురస్రాకార వృత్తం"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"వృత్తం"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"కన్నీటి చుక్క"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"చిహ్న ఆకార మార్పులను వర్తింపజేస్తోంది"</string> <string name="package_state_unknown" msgid="7592128424511031410">"తెలియదు"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"తీసివేయి"</string> diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 1f5c7c87c..2adf4b996 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"ใช้ค่าเริ่มต้นของระบบ"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"สี่เหลี่ยมจัตุรัส"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"สี่เหลี่ยมขอบมน"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"วงกลม"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"หยดน้ำตา"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"ไม่รู้จัก"</string> diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index ff92183d2..4390a3a38 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Gamitin ang default ng system"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Parisukat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Bilog"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Hindi kilala"</string> diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index ff2871265..cb03f5184 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Sistem varsayılanını kullan"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kare"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Kare-daire"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Daire"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Gözyaşı damlası"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Bilinmiyor"</string> diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index c904d414d..70a742fe7 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Використовувати налаштування системи за умовчанням"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Квадрат із заокругленими кутами"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Сльоза"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Невідомо"</string> diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml index 31ac66f51..0a747e6a3 100644 --- a/res/values-ur-rPK/strings.xml +++ b/res/values-ur-rPK/strings.xml @@ -83,14 +83,10 @@ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"نئی ایپس کیلئے"</string> <string name="icon_shape_override_label" msgid="2977264953998281004">"آئیکن کی شکل تبدیل کریں"</string> <string name="icon_shape_system_default" msgid="1709762974822753030">"سسٹم ڈیفالٹ کا استعمال کریں"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"مربع"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"اسکورکل"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"حلقہ"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"آنسو کا قطرہ"</string> <string name="icon_shape_override_progress" msgid="3461735694970239908">"آئيکن کی شکل کی تبدیلیاں لاگو ہو رہی ہیں"</string> <string name="package_state_unknown" msgid="7592128424511031410">"نامعلوم"</string> <string name="abandoned_clean_this" msgid="7610119707847920412">"ہٹائیں"</string> diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml index 716eedde2..d11a60d9b 100644 --- a/res/values-uz-rUZ/strings.xml +++ b/res/values-uz-rUZ/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Standart tizim parametrlaridan foydalanish"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Qirralari aylana kvadrat"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Aylana"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Tomchi"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Noma’lum"</string> diff --git a/res/values-v19/styles.xml b/res/values-v19/styles.xml index cfc7c0f9c..36c09718e 100644 --- a/res/values-v19/styles.xml +++ b/res/values-v19/styles.xml @@ -18,7 +18,7 @@ --> <resources> - <style name="LauncherTheme" parent="@style/BaseLauncherTheme"> + <style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> </style> diff --git a/res/values-v21/styles.xml b/res/values-v21/styles.xml index 8d3de0153..927719cc1 100644 --- a/res/values-v21/styles.xml +++ b/res/values-v21/styles.xml @@ -18,7 +18,7 @@ --> <resources> - <style name="LauncherTheme" parent="@style/BaseLauncherTheme"> + <style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs"> <item name="android:windowTranslucentStatus">false</item> <item name="android:windowTranslucentNavigation">false</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 580a4dda7..bd7fc450f 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Sử dụng mặc định của hệ thống"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Hình vuông"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"Hình vuông cạnh bo tròn"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Hình tròn"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"Hình giọt nước"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Không xác định"</string> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 0a43a9175..3ac74fd10 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"使用系统默认设置"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"方形"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"方圆形"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"圆形"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"泪珠形"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"未知"</string> diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index ae66324aa..97cee9724 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"使用系統預設設定"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"正方形"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"方圓形"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"圓形"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"淚珠形"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 02f63504e..6a75cce10 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"使用系統預設值"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"正方形"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"方圓形"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"圓形"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"淚珠形"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string> diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index bdb46a359..56d9985fb 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -84,14 +84,10 @@ <!-- no translation found for icon_shape_override_label (2977264953998281004) --> <skip /> <string name="icon_shape_system_default" msgid="1709762974822753030">"Sebenzisa okuzenzakalelayo kwesistimu"</string> - <!-- no translation found for icon_shape_square (633575066111622774) --> - <skip /> - <!-- no translation found for icon_shape_squircle (5658049910802669495) --> - <skip /> - <!-- no translation found for icon_shape_circle (6550072265930144217) --> - <skip /> - <!-- no translation found for icon_shape_teardrop (4525869388200835463) --> - <skip /> + <string name="icon_shape_square" msgid="633575066111622774">"Isikwele"</string> + <string name="icon_shape_squircle" msgid="5658049910802669495">"I-Squircle"</string> + <string name="icon_shape_circle" msgid="6550072265930144217">"Indingiliza"</string> + <string name="icon_shape_teardrop" msgid="4525869388200835463">"I-Teardrop"</string> <!-- no translation found for icon_shape_override_progress (3461735694970239908) --> <skip /> <string name="package_state_unknown" msgid="7592128424511031410">"Akwaziwa"</string> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index eaadd475a..b7189d17c 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -20,7 +20,16 @@ <!-- Attributes used for launcher theme --> <attr name="allAppsScrimColor" format="color" /> - <attr name="isPrimaryColorDark" format="boolean" /> + <attr name="popupColorPrimary" format="color" /> + <attr name="popupColorSecondary" format="color" /> + <attr name="popupColorTertiary" format="color" /> + <attr name="isMainColorDark" format="boolean" /> + <attr name="isWorkspaceDarkText" format="boolean" /> + <attr name="workspaceTextColor" format="color" /> + <attr name="workspaceShadowColor" format="color" /> + <attr name="workspaceAmbientShadowColor" format="color"/> + <attr name="workspaceKeyShadowColor" format="color" /> + <attr name="workspaceStatusBarScrim" format="reference" /> <!-- BubbleTextView specific attributes. --> <declare-styleable name="BubbleTextView"> @@ -36,6 +45,8 @@ <attr name="deferShadowGeneration" format="boolean" /> <attr name="customShadows" format="boolean" /> <attr name="centerVertically" format="boolean" /> + <attr name="ambientShadowColor" format="color" /> + <attr name="keyShadowColor" format="color" /> </declare-styleable> <!-- PagedView specific attributes. These attributes are used to customize @@ -119,5 +130,6 @@ <attr name="android:src" /> <attr name="android:shadowColor" /> <attr name="android:elevation" /> + <attr name="android:tint" /> </declare-styleable> </resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index 6deffc139..4f7c1a73d 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -31,13 +31,12 @@ <color name="spring_loaded_highlighted_panel_border_color">#FFF</color> <!-- Popup container --> - <color name="popup_header_background_color">#F5F5F5</color> <!-- Gray 100 --> - <color name="popup_background_color">#FFF</color> <color name="notification_icon_default_color">#757575</color> <!-- Gray 600 --> - <color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 --> <color name="badge_color">#1DE9B6</color> <!-- Teal A400 --> - <color name="system_shortcuts_icon_color">@android:color/tertiary_text_light</color> + <color name="folder_badge_color">#1DE9B6</color> <!-- Teal A400 --> <color name="icon_background">#E0E0E0</color> <!-- Gray 300 --> <color name="legacy_icon_background">#FFFFFF</color> + + <color name="all_apps_bg_hand_fill">#E5E5E5</color> </resources> diff --git a/res/values/config.xml b/res/values/config.xml index 6df556b8d..db1a75da9 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -64,6 +64,9 @@ <!-- The duration of the animation from search hint to text entry --> <integer name="config_searchHintAnimationDuration">50</integer> + <!-- View tag key used to store SpringAnimation data. --> + <item type="id" name="spring_animation_tag" /> + <!-- Workspace --> <!-- The duration (in ms) of the fade animation on the object outlines, used when we are dragging objects around on the home screen. --> @@ -114,9 +117,6 @@ <!-- View ID to use for QSB widget --> <item type="id" name="qsb_widget" /> - <!-- View ID to use for blocked area on the first screen --> - <item type="id" name="workspace_blocked_row" /> - <!-- View ID used by cell layout to jail its content --> <item type="id" name="cell_layout_jail_id" /> diff --git a/res/values/strings.xml b/res/values/strings.xml index 24a7b881a..da6da04c2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -172,12 +172,12 @@ <string name="allow_rotation_desc">When phone is rotated</string> <!-- Text explaining that rotation is disabled in Display settings. 'Display' refers to the Display section in system settings [CHAR LIMIT=100] --> <string name="allow_rotation_blocked_desc">Current Display setting doesn\'t permit rotation</string> - <!-- Title for Icon Badging setting. Tapping this will link to the system Notifications Settings screen where the user can turn off badging globally. [CHAR LIMIT=50] --> - <string name="icon_badging_title">Icon badging</string> + <!-- Title for Notification dots setting. Tapping this will link to the system Notifications settings screen where the user can turn off notification dots globally. [CHAR LIMIT=50] --> + <string name="icon_badging_title">Notification dots</string> <!-- Text to indicate that the system icon badging setting is on [CHAR LIMIT=100] --> - <string name="icon_badging_desc_on">On for all apps</string> + <string name="icon_badging_desc_on">On</string> <!-- Text to indicate that the system icon badging setting is off [CHAR LIMIT=100] --> - <string name="icon_badging_desc_off">Off for all apps</string> + <string name="icon_badging_desc_off">Off</string> <!-- Label for the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=40] --> <string name="auto_add_shortcuts_label">Add icon to Home screen</string> diff --git a/res/values/styles.xml b/res/values/styles.xml index f75ca4eeb..8af6968a6 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -26,32 +26,56 @@ <item name="android:windowNoTitle">true</item> <item name="android:colorEdgeEffect">#FF757575</item> <item name="android:keyboardLayout">@layout/all_apps_search_container</item> + </style> + + <style name="BaseLauncherThemeWithCustomAttrs" parent="@style/BaseLauncherTheme"> <item name="allAppsScrimColor">#DDFFFFFF</item> - <item name="isPrimaryColorDark">false</item> + <item name="popupColorPrimary">#FFF</item> + <item name="popupColorSecondary">#F5F5F5</item> <!-- Gray 100 --> + <item name="popupColorTertiary">#E0E0E0</item> <!-- Gray 300 --> + <item name="isMainColorDark">false</item> + <item name="isWorkspaceDarkText">false</item> + <item name="workspaceTextColor">@android:color/white</item> + <item name="workspaceShadowColor">#B0000000</item> + <item name="workspaceAmbientShadowColor">#33000000</item> + <item name="workspaceKeyShadowColor">#44000000</item> + <item name="workspaceStatusBarScrim">@drawable/workspace_bg</item> </style> - <style name="LauncherTheme" parent="@style/BaseLauncherTheme"></style> + <style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs"></style> + + <style name="LauncherThemeDarkText" parent="@style/LauncherTheme"> + <item name="workspaceTextColor">#FF212121</item> + <item name="workspaceShadowColor">@android:color/transparent</item> + <item name="workspaceAmbientShadowColor">@android:color/transparent</item> + <item name="workspaceKeyShadowColor">@android:color/transparent</item> + <item name="isWorkspaceDarkText">true</item> + <item name="workspaceStatusBarScrim">@null</item> + </style> <style name="LauncherThemeDark" parent="@style/LauncherTheme"> + <item name="android:textColorPrimary">#FFFFFFFF</item> <item name="android:textColorSecondary">#FFFFFFFF</item> <item name="android:textColorTertiary">#CCFFFFFF</item> <item name="android:textColorHint">#A0FFFFFF</item> - <item name="android:colorControlHighlight">#A0FFFFFF</item> <item name="android:colorPrimary">#FF333333</item> <item name="allAppsScrimColor">#33000000</item> - <item name="isPrimaryColorDark">true</item> + <item name="popupColorPrimary">?android:attr/colorPrimary</item> + <item name="popupColorSecondary">#424242</item> <!-- Gray 800 --> + <item name="popupColorTertiary">#757575</item> <!-- Gray 600 --> + <item name="isMainColorDark">true</item> </style> <!-- Theme overrides to element on homescreen, i.e., which are drawn on top on wallpaper. - Various foreground colors are overridden to be white so that they are properly visible on - various wallpapers + Various foreground colors are overridden to be workspaceTextColor so that they are properly + visible on various wallpapers. --> - <style name="HomeScreenElementTheme" parent="@style/LauncherTheme"> - <item name="android:colorEdgeEffect">@android:color/white</item> - <item name="android:textColorPrimary">@android:color/white</item> - <item name="android:textColorSecondary">@android:color/white</item> + <style name="HomeScreenElementTheme"> + <item name="android:colorEdgeEffect">?attr/workspaceTextColor</item> + <item name="android:textColorPrimary">?attr/workspaceTextColor</item> + <item name="android:textColorSecondary">?attr/workspaceTextColor</item> </style> <!-- Theme for the widget container. Overridden on API 26. --> @@ -102,16 +126,14 @@ <style name="BaseIcon.Workspace"> <item name="customShadows">true</item> <item name="android:shadowRadius">2.0</item> - <item name="android:shadowColor">#B0000000</item> + <item name="android:shadowColor">?attr/workspaceShadowColor</item> + <item name="keyShadowColor">?attr/workspaceKeyShadowColor</item> + <item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item> </style> <!-- Theme for the popup container --> - <!-- TODO: Add support for dark theme in shortcuts and widgets popup --> - <style name="IconOnlySystemShortcut" parent="@style/LauncherTheme"> - <item name="android:tint">?android:attr/textColorHint</item> - </style> - <style name="IconWithTextSystemShortcut" parent="@style/LauncherTheme"> - <item name="android:backgroundTint">?android:attr/textColorTertiary</item> + <style name="PopupItem"> + <item name="android:colorControlHighlight">?attr/popupColorTertiary</item> </style> <!-- Drop targets --> @@ -119,15 +141,19 @@ <item name="android:drawablePadding">7.5dp</item> <item name="android:paddingLeft">16dp</item> <item name="android:paddingRight">16dp</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textColor">?attr/workspaceTextColor</item> <item name="android:textSize">@dimen/drop_target_text_size</item> <item name="android:singleLine">true</item> <item name="android:ellipsize">end</item> - <item name="android:shadowColor">@color/default_shadow_color_no_alpha</item> + <item name="android:shadowColor">?attr/workspaceShadowColor</item> <item name="android:shadowDx">0.0</item> <item name="android:shadowDy">1.0</item> <item name="android:shadowRadius">4.0</item> </style> <style name="DropTargetButton" parent="DropTargetButtonBase" /> + + <style name="TextTitle"> + <item name="android:fontFamily">sans-serif</item> + </style> </resources> diff --git a/src/com/android/launcher3/AppFilter.java b/src/com/android/launcher3/AppFilter.java index db8f5dd0e..923835a67 100644 --- a/src/com/android/launcher3/AppFilter.java +++ b/src/com/android/launcher3/AppFilter.java @@ -1,9 +1,14 @@ package com.android.launcher3; import android.content.ComponentName; +import android.content.Context; public class AppFilter { + public static AppFilter newInstance(Context context) { + return Utilities.getOverrideObject(AppFilter.class, context, R.string.app_filter_class); + } + public boolean shouldShowApp(ComponentName app) { return true; } diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java index 84a8bce6e..70be7dae4 100644 --- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java +++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java @@ -12,6 +12,7 @@ import android.os.Handler; import android.util.Log; import com.android.launcher3.LauncherSettings.Favorites; +import com.android.launcher3.model.LoaderTask; import com.android.launcher3.util.ContentWriter; public class AppWidgetsRestoredReceiver extends BroadcastReceiver { @@ -52,7 +53,7 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]); final int state; - if (LauncherModel.isValidProvider(provider)) { + if (LoaderTask.isValidProvider(provider)) { // This will ensure that we show 'Click to setup' UI if required. state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY; } else { diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java index 1e6d89485..514cc0751 100644 --- a/src/com/android/launcher3/BaseRecyclerView.java +++ b/src/com/android/launcher3/BaseRecyclerView.java @@ -48,6 +48,8 @@ public abstract class BaseRecyclerView extends RecyclerView private int mDownY; private int mLastY; + private boolean mScrollBarVisible = true; + public BaseRecyclerView(Context context) { this(context, null); } @@ -199,8 +201,18 @@ public abstract class BaseRecyclerView extends RecyclerView @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); - onUpdateScrollbar(0); - mScrollbar.draw(canvas); + if (mScrollBarVisible) { + onUpdateScrollbar(0); + mScrollbar.draw(canvas); + } + } + + /** + * Sets the scrollbar visibility. The call does not refresh the UI, its the responsibility + * of the caller to call {@link #invalidate()}. + */ + public void setScrollBarVisible(boolean visible) { + mScrollBarVisible = visible; } /** diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 1f7eba812..27e190e5d 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -65,8 +65,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { private static final float AMBIENT_SHADOW_RADIUS = 2.5f; private static final float KEY_SHADOW_RADIUS = 1f; private static final float KEY_SHADOW_OFFSET = 0.5f; - private static final int AMBIENT_SHADOW_COLOR = 0x33000000; - private static final int KEY_SHADOW_COLOR = 0x66000000; private static final int DISPLAY_WORKSPACE = 0; private static final int DISPLAY_ALL_APPS = 1; @@ -82,6 +80,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { private final CheckLongPressHelper mLongPressHelper; private final HolographicOutlineHelper mOutlineHelper; private final StylusEventHelper mStylusEventHelper; + private final int mAmbientShadowColor; + private final int mKeyShadowColor; private boolean mBackgroundSizeChanged; @@ -99,7 +99,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { private BadgeInfo mBadgeInfo; private BadgeRenderer mBadgeRenderer; - private IconPalette mIconPalette; + private IconPalette mBadgePalette; private float mBadgeScale; private boolean mForceHideBadge; private Point mTempSpaceForBadgeOffset = new Point(); @@ -147,6 +147,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false); mDeferShadowGenerationOnTouch = a.getBoolean(R.styleable.BubbleTextView_deferShadowGeneration, false); + mAmbientShadowColor = a.getColor(R.styleable.BubbleTextView_ambientShadowColor, 0x33000000); + mKeyShadowColor = a.getColor(R.styleable.BubbleTextView_keyShadowColor, 0x66000000); int display = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE); int defaultIconSize = grid.iconSizePx; @@ -174,7 +176,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { // Set shadow layer as the larger shadow to that the textView does not clip the shadow. float density = getResources().getDisplayMetrics().density; - setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, AMBIENT_SHADOW_COLOR); + setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor); } else { mBackground = null; } @@ -435,14 +437,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { // We enhance the shadow by drawing the shadow twice float density = getResources().getDisplayMetrics().density; - getPaint().setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, AMBIENT_SHADOW_COLOR); + getPaint().setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor); super.draw(canvas); canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(), getScrollX() + getWidth(), getScrollY() + getHeight(), Region.Op.INTERSECT); getPaint().setShadowLayer( - density * KEY_SHADOW_RADIUS, 0.0f, density * KEY_SHADOW_OFFSET, KEY_SHADOW_COLOR); + density * KEY_SHADOW_RADIUS, 0.0f, density * KEY_SHADOW_OFFSET, mKeyShadowColor); super.draw(canvas); canvas.restore(); @@ -460,7 +462,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { final int scrollX = getScrollX(); final int scrollY = getScrollY(); canvas.translate(scrollX, scrollY); - mBadgeRenderer.draw(canvas, mBadgeInfo, mTempIconBounds, mBadgeScale, + mBadgeRenderer.draw(canvas, mBadgePalette, mBadgeInfo, mTempIconBounds, mBadgeScale, mTempSpaceForBadgeOffset); canvas.translate(-scrollX, -scrollY); } @@ -594,7 +596,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { float newBadgeScale = isBadged ? 1f : 0; mBadgeRenderer = mLauncher.getDeviceProfile().mBadgeRenderer; if (wasBadged || isBadged) { - mIconPalette = ((FastBitmapDrawable) mIcon).getIconPalette(); + mBadgePalette = IconPalette.getBadgePalette(getResources()); + if (mBadgePalette == null) { + mBadgePalette = ((FastBitmapDrawable) mIcon).getIconPalette(); + } // Animate when a badge is first added or when it is removed. if (animate && (wasBadged ^ isBadged) && isShown()) { ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start(); @@ -606,6 +611,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { } } + public IconPalette getBadgePalette() { + return mBadgePalette; + } + /** * Sets the icon for this view based on the layout direction. */ diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 78030ce2a..c2c5c27db 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -236,7 +236,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { for (int i = 0; i < mDragOutlines.length; i++) { mDragOutlines[i] = new Rect(-1, -1, -1, -1); } - mDragOutlinePaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary)); + mDragOutlinePaint.setColor(Themes.getAttrColor(context, R.attr.workspaceTextColor)); // When dragging things around the home screens, we show a green outline of // where the item will land. The outlines gradually fade out, leaving a trail diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 508fc3406..9bb56d603 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -532,14 +532,6 @@ public class DeviceProfile { workspacePadding.bottom); workspace.setPageSpacing(getWorkspacePageSpacing()); - // Only display when enabled - if (FeatureFlags.QSB_ON_FIRST_SCREEN) { - View qsbContainer = launcher.getQsbContainer(); - lp = (FrameLayout.LayoutParams) qsbContainer.getLayoutParams(); - lp.topMargin = mInsets.top + workspacePadding.top; - qsbContainer.setLayoutParams(lp); - } - // Layout the hotseat Hotseat hotseat = (Hotseat) launcher.findViewById(R.id.hotseat); lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams(); diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java index a096a1ddf..199baaf58 100644 --- a/src/com/android/launcher3/FastBitmapDrawable.java +++ b/src/com/android/launcher3/FastBitmapDrawable.java @@ -124,7 +124,7 @@ public class FastBitmapDrawable extends Drawable { public IconPalette getIconPalette() { if (mIconPalette == null) { mIconPalette = IconPalette.fromDominantColor(Utilities - .findDominantColorByHue(mBitmap, 20)); + .findDominantColorByHue(mBitmap, 20), true /* desaturateBackground */); } return mIconPalette; } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 0075887ee..dd0d2b804 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -127,6 +127,7 @@ import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.PendingRequestArgs; import com.android.launcher3.util.TestingUtils; +import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.ViewOnDrawExecutor; import com.android.launcher3.widget.PendingAddShortcutInfo; @@ -224,7 +225,6 @@ public class Launcher extends BaseActivity private View mLauncherView; @Thunk DragLayer mDragLayer; private DragController mDragController; - private View mQsbContainer; public View mWeightWatcher; @@ -272,7 +272,6 @@ public class Launcher extends BaseActivity private Handler mHandler = new Handler(); private boolean mIsResumeFromActionScreenOff; private boolean mHasFocus = false; - private boolean mAttached = false; private ObjectAnimator mScrimAnimator; @@ -369,7 +368,7 @@ public class Launcher extends BaseActivity WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(this); wallpaperColorInfo.setOnThemeChangeListener(this); - overrideTheme(wallpaperColorInfo.isDark()); + overrideTheme(wallpaperColorInfo.isDark(), wallpaperColorInfo.supportsDarkText()); super.onCreate(savedInstanceState); @@ -467,6 +466,13 @@ public class Launcher extends BaseActivity if (mLauncherCallbacks != null) { mLauncherCallbacks.onCreate(savedInstanceState); } + + // Listen for broadcasts screen off + registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF)); + + if (Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)) { + activateLightSystemBars(true, true, true); + } } @Override @@ -474,9 +480,11 @@ public class Launcher extends BaseActivity recreate(); } - protected void overrideTheme(boolean isDark) { + protected void overrideTheme(boolean isDark, boolean supportsDarkText) { if (isDark) { setTheme(R.style.LauncherThemeDark); + } else if (supportsDarkText) { + setTheme(R.style.LauncherThemeDarkText); } } @@ -1278,9 +1286,7 @@ public class Launcher extends BaseActivity private void setupViews() { mDragLayer = (DragLayer) findViewById(R.id.drag_layer); mFocusHandler = mDragLayer.getFocusIndicatorHelper(); - mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace); - mQsbContainer = mDragLayer.findViewById(mDeviceProfile.isVerticalBarLayout() - ? R.id.workspace_blocked_row : R.id.qsb_container); + mWorkspace = mDragLayer.findViewById(R.id.workspace); mWorkspace.initParentViews(mDragLayer); mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN @@ -1587,13 +1593,7 @@ public class Launcher extends BaseActivity public void onAttachedToWindow() { super.onAttachedToWindow(); - // Listen for broadcasts related to user-presence - final IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_OFF); - registerReceiver(mReceiver, filter); FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView()); - mAttached = true; - if (mLauncherCallbacks != null) { mLauncherCallbacks.onAttachedToWindow(); } @@ -1602,10 +1602,6 @@ public class Launcher extends BaseActivity @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); - if (mAttached) { - unregisterReceiver(mReceiver); - mAttached = false; - } if (mLauncherCallbacks != null) { mLauncherCallbacks.onDetachedFromWindow(); @@ -1667,10 +1663,6 @@ public class Launcher extends BaseActivity return mWorkspace; } - public View getQsbContainer() { - return mQsbContainer; - } - public Hotseat getHotseat() { return mHotseat; } @@ -1846,6 +1838,7 @@ public class Launcher extends BaseActivity public void onDestroy() { super.onDestroy(); + unregisterReceiver(mReceiver); mWorkspace.removeCallbacks(mBuildLayersRunnable); mWorkspace.removeFolderListeners(); @@ -3970,7 +3963,7 @@ public class Launcher extends BaseActivity * refreshes the widgets and shortcuts associated with the given package/user */ public void refreshAndBindWidgetsForPackageUser(@Nullable PackageUserKey packageUser) { - mModel.refreshAndBindWidgetsAndShortcuts(this, mWidgetsView.isEmpty(), packageUser); + mModel.refreshAndBindWidgetsAndShortcuts(packageUser); } public void lockScreenOrientation() { diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 27ccabea9..cf20febd5 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -93,9 +93,7 @@ public class LauncherAppState { mInvariantDeviceProfile = new InvariantDeviceProfile(mContext); mIconCache = new IconCache(mContext, mInvariantDeviceProfile); mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache); - - mModel = new LauncherModel(this, mIconCache, - Utilities.getOverrideObject(AppFilter.class, mContext, R.string.app_filter_class)); + mModel = new LauncherModel(this, mIconCache, AppFilter.newInstance(mContext)); LauncherAppsCompat.getInstance(mContext).addOnAppsChangedCallback(mModel); diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index ee06d9e58..48c5c562c 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -16,7 +16,6 @@ package com.android.launcher3; -import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentProviderOperation; @@ -24,62 +23,40 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.LauncherActivityInfo; -import android.content.pm.PackageInstaller; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; -import android.os.SystemClock; -import android.os.Trace; import android.os.UserHandle; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; -import android.util.LongSparseArray; -import android.util.MutableInt; import android.util.Pair; -import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.LauncherAppsCompat; -import com.android.launcher3.compat.PackageInstallerCompat; import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; import com.android.launcher3.compat.UserManagerCompat; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dynamicui.ExtractionUtils; -import com.android.launcher3.folder.Folder; -import com.android.launcher3.folder.FolderIcon; -import com.android.launcher3.folder.FolderIconPreviewVerifier; import com.android.launcher3.graphics.LauncherIcons; -import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.AddWorkspaceItemsTask; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.CacheDataUpdatedTask; import com.android.launcher3.model.ExtendedModelTask; -import com.android.launcher3.model.GridSizeMigrationTask; -import com.android.launcher3.model.LoaderCursor; import com.android.launcher3.model.LoaderResults; +import com.android.launcher3.model.LoaderTask; import com.android.launcher3.model.ModelWriter; import com.android.launcher3.model.PackageInstallStateChangedTask; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.model.PackageUpdatedTask; -import com.android.launcher3.model.SdCardAvailableReceiver; import com.android.launcher3.model.ShortcutsChangedTask; import com.android.launcher3.model.UserLockStateChangedTask; import com.android.launcher3.model.WidgetItem; -import com.android.launcher3.model.WidgetsModel; -import com.android.launcher3.provider.ImportDataTask; import com.android.launcher3.provider.LauncherDbUtils; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.ShortcutInfoCompat; -import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.util.ComponentKey; -import com.android.launcher3.util.LooperIdleLock; -import com.android.launcher3.util.ManagedProfileHeuristic; import com.android.launcher3.util.MultiHashMap; -import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Provider; @@ -90,12 +67,9 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; @@ -106,7 +80,7 @@ import java.util.concurrent.Executor; */ public class LauncherModel extends BroadcastReceiver implements LauncherAppsCompat.OnAppsChangedCallbackCompat { - static final boolean DEBUG_LOADERS = false; + static final boolean DEBUG_TASKS = false; private static final boolean DEBUG_RECEIVER = false; static final String TAG = "Launcher.Model"; @@ -114,9 +88,9 @@ public class LauncherModel extends BroadcastReceiver private final MainThreadExecutor mUiExecutor = new MainThreadExecutor(); @Thunk final LauncherAppState mApp; @Thunk final Object mLock = new Object(); - @Thunk LoaderTask mLoaderTask; + @Thunk + LoaderTask mLoaderTask; @Thunk boolean mIsLoaderTaskRunning; - @Thunk boolean mHasLoaderCompletedOnce; @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); static { @@ -139,10 +113,13 @@ public class LauncherModel extends BroadcastReceiver // < only access in worker thread > private final AllAppsList mBgAllAppsList; - // Entire list of widgets. - private final WidgetsModel mBgWidgetsModel; - private boolean mHasShortcutHostPermission; + /** + * All the static data should be accessed on the background thread, A lock should be acquired + * on this object when accessing any data from this model. + */ + static final BgDataModel sBgDataModel = new BgDataModel(); + // Runnable to check if the shortcuts permission has changed. private final Runnable mShortcutPermissionCheckRunnable = new Runnable() { @Override @@ -150,26 +127,13 @@ public class LauncherModel extends BroadcastReceiver if (mModelLoaded) { boolean hasShortcutHostPermission = DeepShortcutManager.getInstance(mApp.getContext()).hasHostPermission(); - if (hasShortcutHostPermission != mHasShortcutHostPermission) { + if (hasShortcutHostPermission != sBgDataModel.hasShortcutHostPermission) { forceReload(); } } } }; - /** - * All the static data should be accessed on the background thread, A lock should be acquired - * on this object when accessing any data from this model. - */ - static final BgDataModel sBgDataModel = new BgDataModel(); - - // </ only access in worker thread > - - private final IconCache mIconCache; - - private final LauncherAppsCompat mLauncherApps; - private final UserManagerCompat mUserManager; - public interface Callbacks { public boolean setLoadOnResume(); public int getCurrentWorkspaceScreen(); @@ -204,14 +168,8 @@ public class LauncherModel extends BroadcastReceiver } LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) { - Context context = app.getContext(); mApp = app; mBgAllAppsList = new AllAppsList(iconCache, appFilter); - mBgWidgetsModel = new WidgetsModel(iconCache, appFilter); - mIconCache = iconCache; - - mLauncherApps = LauncherAppsCompat.getInstance(context); - mUserManager = UserManagerCompat.getInstance(context); } /** Runs the specified runnable immediately if called from the worker thread, otherwise it is @@ -539,9 +497,10 @@ public class LauncherModel extends BroadcastReceiver // issues that arise from that. loaderResults.bindAllApps(); loaderResults.bindDeepShortcuts(); + loaderResults.bindWidgets(); return true; } else { - mLoaderTask = new LoaderTask(mApp.getContext(), loaderResults); + mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, loaderResults); sWorker.post(mLoaderTask); } } @@ -588,763 +547,42 @@ public class LauncherModel extends BroadcastReceiver }); } - /** - * Runnable for the thread that loads the contents of the launcher: - * - workspace icons - * - widgets - * - all apps icons - * - deep shortcuts within apps - */ - private class LoaderTask implements Runnable { - private Context mContext; - private final LoaderResults mResults; - - private boolean mStopped; - - LoaderTask(Context context, LoaderResults results) { - mContext = context; - mResults = results; - } + public class LoaderTransaction implements AutoCloseable { - private void waitForIdle() { - // Wait until the either we're stopped or the other threads are done. - // This way we don't start loading all apps until the workspace has settled - // down. - synchronized (LoaderTask.this) { - LooperIdleLock idleLock = new LooperIdleLock(this, Looper.getMainLooper()); - // Just in case mFlushingWorkerThread changes but we aren't woken up, - // wait no longer than 1sec at a time - while (!mStopped && idleLock.awaitLocked(1000)); - } - } - - private void verifyNotStopped() throws CancellationException { - synchronized (LoaderTask.this) { - if (mStopped) { - throw new CancellationException("Loader stopped"); - } - } - } + private final LoaderTask mTask; - public void run() { + private LoaderTransaction(LoaderTask task) throws CancellationException { synchronized (mLock) { - if (mStopped) { - return; + if (mLoaderTask != task) { + throw new CancellationException("Loader already stopped"); } + mTask = task; mIsLoaderTaskRunning = true; - } - - try { - long now = 0; - if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace"); - loadWorkspace(); - - verifyNotStopped(); - if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace"); - mResults.bindWorkspace(); - - // Take a break - if (DEBUG_LOADERS) { - Log.d(TAG, "step 1 completed, wait for idle"); - now = SystemClock.uptimeMillis(); - } - waitForIdle(); - if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms"); - verifyNotStopped(); - - // second step - if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps"); - loadAllApps(); - - if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Binding all apps"); - verifyNotStopped(); - mResults.bindAllApps(); - - verifyNotStopped(); - if (DEBUG_LOADERS) Log.d(TAG, "step 2.3: Update icon cache"); - updateIconCache(); - - // Take a break - if (DEBUG_LOADERS) { - Log.d(TAG, "step 2 completed, wait for idle"); - now = SystemClock.uptimeMillis(); - } - waitForIdle(); - if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms"); - verifyNotStopped(); - - // third step - if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts"); - loadDeepShortcuts(); - - verifyNotStopped(); - if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts"); - mResults.bindDeepShortcuts(); - - // Take a break - if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle"); - waitForIdle(); - verifyNotStopped(); - - // fourth step - if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets"); - refreshAndBindWidgetsAndShortcuts(getCallback(), false /* bindFirst */, - null /* packageUser */); - - synchronized (mLock) { - // Everything loaded bind the data. - mModelLoaded = true; - mHasLoaderCompletedOnce = true; - } - } catch (CancellationException e) { - // Loader stopped, ignore - } finally { - // Clear out this reference, otherwise we end up holding it until all of the - // callback runnables are done. - mContext = null; - - synchronized (mLock) { - // If we are still the last one to be scheduled, remove ourselves. - if (mLoaderTask == this) { - mLoaderTask = null; - } - mIsLoaderTaskRunning = false; - } + mModelLoaded = false; } } - public void stopLocked() { - synchronized (LoaderTask.this) { - mStopped = true; - this.notify(); - } - } - - private void loadWorkspace() { - if (LauncherAppState.PROFILE_STARTUP) { - Trace.beginSection("Loading Workspace"); - } - - final Context context = mContext; - final ContentResolver contentResolver = context.getContentResolver(); - final PackageManagerHelper pmHelper = new PackageManagerHelper(context); - final boolean isSafeMode = pmHelper.isSafeMode(); - final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); - final DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(context); - final boolean isSdCardReady = Utilities.isBootCompleted(); - final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>(); - - boolean clearDb = false; - try { - ImportDataTask.performImportIfPossible(context); - } catch (Exception e) { - // Migration failed. Clear workspace. - clearDb = true; - } - - if (!clearDb && GridSizeMigrationTask.ENABLED && - !GridSizeMigrationTask.migrateGridIfNeeded(mContext)) { - // Migration failed. Clear workspace. - clearDb = true; - } - - if (clearDb) { - Log.d(TAG, "loadWorkspace: resetting launcher database"); - LauncherSettings.Settings.call(contentResolver, - LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB); - } - - Log.d(TAG, "loadWorkspace: loading default favorites"); - LauncherSettings.Settings.call(contentResolver, - LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES); - - synchronized (sBgDataModel) { - sBgDataModel.clear(); - - final HashMap<String, Integer> installingPkgs = PackageInstallerCompat - .getInstance(mContext).updateAndGetActiveSessionCache(); - sBgDataModel.workspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); - - Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>(); - final LoaderCursor c = new LoaderCursor(contentResolver.query( - LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp); - - HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null; - - try { - final int appWidgetIdIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.APPWIDGET_ID); - final int appWidgetProviderIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.APPWIDGET_PROVIDER); - final int spanXIndex = c.getColumnIndexOrThrow - (LauncherSettings.Favorites.SPANX); - final int spanYIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.SPANY); - final int rankIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.RANK); - final int optionsIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.OPTIONS); - - final LongSparseArray<UserHandle> allUsers = c.allUsers; - final LongSparseArray<Boolean> quietMode = new LongSparseArray<>(); - final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>(); - for (UserHandle user : mUserManager.getUserProfiles()) { - long serialNo = mUserManager.getSerialNumberForUser(user); - allUsers.put(serialNo, user); - quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user)); - - boolean userUnlocked = mUserManager.isUserUnlocked(user); - - // We can only query for shortcuts when the user is unlocked. - if (userUnlocked) { - List<ShortcutInfoCompat> pinnedShortcuts = - shortcutManager.queryForPinnedShortcuts(null, user); - if (shortcutManager.wasLastCallSuccess()) { - for (ShortcutInfoCompat shortcut : pinnedShortcuts) { - shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), - shortcut); - } - } else { - // Shortcut manager can fail due to some race condition when the - // lock state changes too frequently. For the purpose of the loading - // shortcuts, consider the user is still locked. - userUnlocked = false; - } - } - unlockedUsers.put(serialNo, userUnlocked); - } - - ShortcutInfo info; - LauncherAppWidgetInfo appWidgetInfo; - Intent intent; - String targetPkg; - - FolderIconPreviewVerifier verifier = - new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile()); - while (!mStopped && c.moveToNext()) { - try { - if (c.user == null) { - // User has been deleted, remove the item. - c.markDeleted("User has been deleted"); - continue; - } - - boolean allowMissingTarget = false; - switch (c.itemType) { - case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: - case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: - case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: - intent = c.parseIntent(); - if (intent == null) { - c.markDeleted("Invalid or null intent"); - continue; - } - - int disabledState = quietMode.get(c.serialNumber) ? - ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0; - ComponentName cn = intent.getComponent(); - targetPkg = cn == null ? intent.getPackage() : cn.getPackageName(); - - if (!Process.myUserHandle().equals(c.user)) { - if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) { - c.markDeleted("Legacy shortcuts are only allowed for default user"); - continue; - } else if (c.restoreFlag != 0) { - // Don't restore items for other profiles. - c.markDeleted("Restore from managed profile not supported"); - continue; - } - } - if (TextUtils.isEmpty(targetPkg) && - c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) { - c.markDeleted("Only legacy shortcuts can have null package"); - continue; - } - - // If there is no target package, its an implicit intent - // (legacy shortcut) which is always valid - boolean validTarget = TextUtils.isEmpty(targetPkg) || - launcherApps.isPackageEnabledForProfile(targetPkg, c.user); - - if (cn != null && validTarget) { - // If the apk is present and the shortcut points to a specific - // component. - - // If the component is already present - if (launcherApps.isActivityEnabledForProfile(cn, c.user)) { - // no special handling necessary for this item - c.markRestored(); - } else { - if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) { - // We allow auto install apps to have their intent - // updated after an install. - intent = pmHelper.getAppLaunchIntent(targetPkg, c.user); - if (intent != null) { - c.restoreFlag = 0; - c.updater().put( - LauncherSettings.Favorites.INTENT, - intent.toUri(0)).commit(); - cn = intent.getComponent(); - } else { - c.markDeleted("Unable to find a launch target"); - continue; - } - } else { - // The app is installed but the component is no - // longer available. - c.markDeleted("Invalid component removed: " + cn); - continue; - } - } - } - // else if cn == null => can't infer much, leave it - // else if !validPkg => could be restored icon or missing sd-card - - if (!TextUtils.isEmpty(targetPkg) && !validTarget) { - // Points to a valid app (superset of cn != null) but the apk - // is not available. - - if (c.restoreFlag != 0) { - // Package is not yet available but might be - // installed later. - FileLog.d(TAG, "package not yet restored: " + targetPkg); - - if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) { - // Restore has started once. - } else if (installingPkgs.containsKey(targetPkg)) { - // App restore has started. Update the flag - c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED; - c.updater().commit(); - } else { - c.markDeleted("Unrestored app removed: " + targetPkg); - continue; - } - } else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) { - // Package is present but not available. - disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; - // Add the icon on the workspace anyway. - allowMissingTarget = true; - } else if (!isSdCardReady) { - // SdCard is not ready yet. Package might get available, - // once it is ready. - Log.d(TAG, "Missing pkg, will check later: " + targetPkg); - pendingPackages.addToList(c.user, targetPkg); - // Add the icon on the workspace anyway. - allowMissingTarget = true; - } else { - // Do not wait for external media load anymore. - c.markDeleted("Invalid package removed: " + targetPkg); - continue; - } - } - - if (validTarget) { - // The shortcut points to a valid target (either no target - // or something which is ready to be used) - c.markRestored(); - } - - boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() && - !verifier.isItemInPreview(c.getInt(rankIndex)); - - if (c.restoreFlag != 0) { - // Already verified above that user is same as default user - info = c.getRestoredItemInfo(intent); - } else if (c.itemType == - LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { - info = c.getAppShortcutInfo( - intent, allowMissingTarget, useLowResIcon); - } else if (c.itemType == - LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { - - ShortcutKey key = ShortcutKey.fromIntent(intent, c.user); - if (unlockedUsers.get(c.serialNumber)) { - ShortcutInfoCompat pinnedShortcut = - shortcutKeyToPinnedShortcuts.get(key); - if (pinnedShortcut == null) { - // The shortcut is no longer valid. - c.markDeleted("Pinned shortcut not found"); - continue; - } - info = new ShortcutInfo(pinnedShortcut, context); - info.iconBitmap = LauncherIcons - .createShortcutIcon(pinnedShortcut, context); - if (pmHelper.isAppSuspended( - pinnedShortcut.getPackage(), info.user)) { - info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; - } - intent = info.intent; - } else { - // Create a shortcut info in disabled mode for now. - info = c.loadSimpleShortcut(); - info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER; - } - } else { // item type == ITEM_TYPE_SHORTCUT - info = c.loadSimpleShortcut(); - - // Shortcuts are only available on the primary profile - if (!TextUtils.isEmpty(targetPkg) - && pmHelper.isAppSuspended(targetPkg, c.user)) { - disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; - } - - // App shortcuts that used to be automatically added to Launcher - // didn't always have the correct intent flags set, so do that - // here - if (intent.getAction() != null && - intent.getCategories() != null && - intent.getAction().equals(Intent.ACTION_MAIN) && - intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { - intent.addFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - } - } - - if (info != null) { - c.applyCommonProperties(info); - - info.intent = intent; - info.rank = c.getInt(rankIndex); - info.spanX = 1; - info.spanY = 1; - info.isDisabled |= disabledState; - if (isSafeMode && !Utilities.isSystemApp(context, intent)) { - info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; - } - - if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) { - Integer progress = installingPkgs.get(targetPkg); - if (progress != null) { - info.setInstallProgress(progress); - } else { - info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE; - } - } - - c.checkAndAddItem(info, sBgDataModel); - } else { - throw new RuntimeException("Unexpected null ShortcutInfo"); - } - break; - - case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: - FolderInfo folderInfo = sBgDataModel.findOrMakeFolder(c.id); - c.applyCommonProperties(folderInfo); - - // Do not trim the folder label, as is was set by the user. - folderInfo.title = c.getString(c.titleIndex); - folderInfo.spanX = 1; - folderInfo.spanY = 1; - folderInfo.options = c.getInt(optionsIndex); - - // no special handling required for restored folders - c.markRestored(); - - c.checkAndAddItem(folderInfo, sBgDataModel); - break; - - case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: - case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: - // Read all Launcher-specific widget details - boolean customWidget = c.itemType == - LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; - - int appWidgetId = c.getInt(appWidgetIdIndex); - String savedProvider = c.getString(appWidgetProviderIndex); - - final ComponentName component = - ComponentName.unflattenFromString(savedProvider); - - final boolean isIdValid = !c.hasRestoreFlag( - LauncherAppWidgetInfo.FLAG_ID_NOT_VALID); - final boolean wasProviderReady = !c.hasRestoreFlag( - LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY); - - if (widgetProvidersMap == null) { - widgetProvidersMap = AppWidgetManagerCompat - .getInstance(mContext).getAllProvidersMap(); - } - final AppWidgetProviderInfo provider = widgetProvidersMap.get( - new ComponentKey( - ComponentName.unflattenFromString(savedProvider), - c.user)); - - final boolean isProviderReady = isValidProvider(provider); - if (!isSafeMode && !customWidget && - wasProviderReady && !isProviderReady) { - c.markDeleted( - "Deleting widget that isn't installed anymore: " - + provider); - } else { - if (isProviderReady) { - appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, - provider.provider); - - // The provider is available. So the widget is either - // available or not available. We do not need to track - // any future restore updates. - int status = c.restoreFlag & - ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; - if (!wasProviderReady) { - // If provider was not previously ready, update the - // status and UI flag. - - // Id would be valid only if the widget restore broadcast was received. - if (isIdValid) { - status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; - } else { - status &= ~LauncherAppWidgetInfo - .FLAG_PROVIDER_NOT_READY; - } - } - appWidgetInfo.restoreStatus = status; - } else { - Log.v(TAG, "Widget restore pending id=" + c.id - + " appWidgetId=" + appWidgetId - + " status =" + c.restoreFlag); - appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, - component); - appWidgetInfo.restoreStatus = c.restoreFlag; - Integer installProgress = installingPkgs.get(component.getPackageName()); - - if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) { - // Restore has started once. - } else if (installProgress != null) { - // App restore has started. Update the flag - appWidgetInfo.restoreStatus |= - LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; - } else if (!isSafeMode) { - c.markDeleted("Unrestored widget removed: " + component); - continue; - } - - appWidgetInfo.installProgress = - installProgress == null ? 0 : installProgress; - } - if (appWidgetInfo.hasRestoreFlag( - LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) { - appWidgetInfo.bindOptions = c.parseIntent(); - } - - c.applyCommonProperties(appWidgetInfo); - appWidgetInfo.spanX = c.getInt(spanXIndex); - appWidgetInfo.spanY = c.getInt(spanYIndex); - appWidgetInfo.user = c.user; - - if (!c.isOnWorkspaceOrHotseat()) { - c.markDeleted("Widget found where container != " + - "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); - continue; - } - - if (!customWidget) { - String providerName = - appWidgetInfo.providerName.flattenToString(); - if (!providerName.equals(savedProvider) || - (appWidgetInfo.restoreStatus != c.restoreFlag)) { - c.updater() - .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, - providerName) - .put(LauncherSettings.Favorites.RESTORED, - appWidgetInfo.restoreStatus) - .commit(); - } - } - - if (appWidgetInfo.restoreStatus != - LauncherAppWidgetInfo.RESTORE_COMPLETED) { - String pkg = appWidgetInfo.providerName.getPackageName(); - appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg); - appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user; - mIconCache.getTitleAndIconForApp( - appWidgetInfo.pendingItemInfo, false); - } - - c.checkAndAddItem(appWidgetInfo, sBgDataModel); - } - break; - } - } catch (Exception e) { - Log.e(TAG, "Desktop items loading interrupted", e); - } - } - } finally { - Utilities.closeSilently(c); - } - - // Break early if we've stopped loading - if (mStopped) { - sBgDataModel.clear(); - return; - } - - // Remove dead items - if (c.commitDeleted()) { - // Remove any empty folder - ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings - .call(contentResolver, - LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS) - .getSerializable(LauncherSettings.Settings.EXTRA_VALUE); - for (long folderId : deletedFolderIds) { - sBgDataModel.workspaceItems.remove(sBgDataModel.folders.get(folderId)); - sBgDataModel.folders.remove(folderId); - sBgDataModel.itemsIdMap.remove(folderId); - } - - // Remove any ghost widgets - LauncherSettings.Settings.call(contentResolver, - LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS); - } - - // Unpin shortcuts that don't exist on the workspace. - HashSet<ShortcutKey> pendingShortcuts = - InstallShortcutReceiver.getPendingShortcuts(context); - for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) { - MutableInt numTimesPinned = sBgDataModel.pinnedShortcutCounts.get(key); - if ((numTimesPinned == null || numTimesPinned.value == 0) - && !pendingShortcuts.contains(key)) { - // Shortcut is pinned but doesn't exist on the workspace; unpin it. - shortcutManager.unpinShortcut(key); - } - } - - FolderIconPreviewVerifier verifier = - new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile()); - // Sort the folder items and make sure all items in the preview are high resolution. - for (FolderInfo folder : sBgDataModel.folders) { - Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR); - verifier.setFolderInfo(folder); - - int numItemsInPreview = 0; - for (ShortcutInfo info : folder.contents) { - if (info.usingLowResIcon - && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION - && verifier.isItemInPreview(info.rank)) { - mIconCache.getTitleAndIcon(info, false); - numItemsInPreview++; - } - - if (numItemsInPreview >= FolderIcon.NUM_ITEMS_IN_PREVIEW) { - break; - } - } - } - - c.commitRestoredItems(); - if (!isSdCardReady && !pendingPackages.isEmpty()) { - context.registerReceiver( - new SdCardAvailableReceiver( - LauncherModel.this, mContext, pendingPackages), - new IntentFilter(Intent.ACTION_BOOT_COMPLETED), - null, - sWorker); - } - - // Remove any empty screens - ArrayList<Long> unusedScreens = new ArrayList<>(sBgDataModel.workspaceScreens); - for (ItemInfo item: sBgDataModel.itemsIdMap) { - long screenId = item.screenId; - if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && - unusedScreens.contains(screenId)) { - unusedScreens.remove(screenId); - } - } - - // If there are any empty screens remove them, and update. - if (unusedScreens.size() != 0) { - sBgDataModel.workspaceScreens.removeAll(unusedScreens); - updateWorkspaceScreenOrder(context, sBgDataModel.workspaceScreens); - } - } - if (LauncherAppState.PROFILE_STARTUP) { - Trace.endSection(); - } - } - - private void updateIconCache() { - // Ignore packages which have a promise icon. - HashSet<String> packagesToIgnore = new HashSet<>(); - synchronized (sBgDataModel) { - for (ItemInfo info : sBgDataModel.itemsIdMap) { - if (info instanceof ShortcutInfo) { - ShortcutInfo si = (ShortcutInfo) info; - if (si.isPromise() && si.getTargetComponent() != null) { - packagesToIgnore.add(si.getTargetComponent().getPackageName()); - } - } else if (info instanceof LauncherAppWidgetInfo) { - LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info; - if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) { - packagesToIgnore.add(lawi.providerName.getPackageName()); - } - } - } + public void commit() { + synchronized (mLock) { + // Everything loaded bind the data. + mModelLoaded = true; } - mIconCache.updateDbIcons(packagesToIgnore); } - private void loadAllApps() { - final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; - - final List<UserHandle> profiles = mUserManager.getUserProfiles(); - - // Clear the list of apps - mBgAllAppsList.clear(); - for (UserHandle user : profiles) { - // Query for the set of apps - final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; - final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user); - if (DEBUG_LOADERS) { - Log.d(TAG, "getActivityList took " - + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user); - Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user); - } - // Fail if we don't have any apps - // TODO: Fix this. Only fail for the current user. - if (apps == null || apps.isEmpty()) { - return; - } - boolean quietMode = mUserManager.isQuietModeEnabled(user); - // Create the ApplicationInfos - for (int i = 0; i < apps.size(); i++) { - LauncherActivityInfo app = apps.get(i); - // This builds the icon bitmaps. - mBgAllAppsList.add(new AppInfo(app, user, quietMode), app); - } - - ManagedProfileHeuristic.onAllAppsLoaded(mContext, apps, user); - } - - if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) { - // get all active sessions and add them to the all apps list - PackageInstallerCompat installer = PackageInstallerCompat.getInstance(mContext); - for (PackageInstaller.SessionInfo info : installer.getAllVerifiedSessions()) { - mBgAllAppsList.addPromiseApp(mContext, - PackageInstallInfo.fromInstallingState(info)); + @Override + public void close() { + synchronized (mLock) { + // If we are still the last one to be scheduled, remove ourselves. + if (mLoaderTask == mTask) { + mLoaderTask = null; } - } - - mBgAllAppsList.added = new ArrayList<>(); - if (DEBUG_LOADERS) { - Log.d(TAG, "All apps loaded in in " - + (SystemClock.uptimeMillis() - loadTime) + "ms"); + mIsLoaderTaskRunning = false; } } + } - private void loadDeepShortcuts() { - sBgDataModel.deepShortcutMap.clear(); - DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(mContext); - mHasShortcutHostPermission = shortcutManager.hasHostPermission(); - if (mHasShortcutHostPermission) { - for (UserHandle user : mUserManager.getUserProfiles()) { - if (mUserManager.isUserUnlocked(user)) { - List<ShortcutInfoCompat> shortcuts = - shortcutManager.queryForAllShortcuts(user); - sBgDataModel.updateDeepShortcutMap(null, user, shortcuts); - } - } - } - } + public LoaderTransaction beginLoader(LoaderTask task) throws CancellationException { + return new LoaderTransaction(task); } /** @@ -1370,12 +608,6 @@ public class LauncherModel extends BroadcastReceiver } public void enqueueModelUpdateTask(BaseModelUpdateTask task) { - if (!mModelLoaded && mLoaderTask == null) { - if (DEBUG_LOADERS) { - Log.d(TAG, "enqueueModelUpdateTask Ignoring task since loader is pending=" + task); - } - return; - } task.init(this); runOnWorkerThread(task); } @@ -1404,8 +636,11 @@ public class LauncherModel extends BroadcastReceiver } @Override - public void run() { - if (!mModel.mHasLoaderCompletedOnce) { + public final void run() { + if (!mModel.mModelLoaded) { + if (DEBUG_TASKS) { + Log.d(TAG, "Ignoring model task since loader is pending=" + this); + } // Loader has not yet run. return; } @@ -1465,43 +700,16 @@ public class LauncherModel extends BroadcastReceiver }); } - private void bindWidgetsModel(final Callbacks callbacks) { - final MultiHashMap<PackageItemInfo, WidgetItem> widgets - = mBgWidgetsModel.getWidgetsMap().clone(); - mUiExecutor.execute(new Runnable() { - @Override - public void run() { - Callbacks cb = getCallback(); - if (callbacks == cb && cb != null) { - callbacks.bindAllWidgets(widgets); - } - } - }); - } - - public void refreshAndBindWidgetsAndShortcuts(final Callbacks callbacks, - final boolean bindFirst, @Nullable final PackageUserKey packageUser) { - runOnWorkerThread(new Runnable() { + public void refreshAndBindWidgetsAndShortcuts(@Nullable final PackageUserKey packageUser) { + enqueueModelUpdateTask(new ExtendedModelTask() { @Override - public void run() { - if (bindFirst && !mBgWidgetsModel.isEmpty()) { - bindWidgetsModel(callbacks); - } - ArrayList<WidgetItem> widgets = mBgWidgetsModel.update( - mApp.getContext(), packageUser); - bindWidgetsModel(callbacks); - - // update the Widget entries inside DB on the worker thread. - mApp.getWidgetCache().removeObsoletePreviews(widgets, packageUser); + public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { + dataModel.widgetsModel.update(app, packageUser); + bindUpdatedWidgets(dataModel); } }); } - static boolean isValidProvider(AppWidgetProviderInfo provider) { - return (provider != null) && (provider.provider != null) - && (provider.provider.getPackageName() != null); - } - public void dumpState(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { if (args.length > 0 && TextUtils.equals(args[0], "--all")) { writer.println(prefix + "All apps list: size=" + mBgAllAppsList.data.size()); diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java index f8196e5f6..c3d3bb3df 100644 --- a/src/com/android/launcher3/PinchAnimationManager.java +++ b/src/com/android/launcher3/PinchAnimationManager.java @@ -56,11 +56,10 @@ public class PinchAnimationManager { private static final LinearInterpolator INTERPOLATOR = new LinearInterpolator(); private static final int INDEX_HOTSEAT = 0; - private static final int INDEX_QSB = 1; - private static final int INDEX_OVERVIEW_PANEL_BUTTONS = 2; - private static final int INDEX_SCRIM = 3; + private static final int INDEX_OVERVIEW_PANEL_BUTTONS = 1; + private static final int INDEX_SCRIM = 2; - private final Animator[] mAnimators = new Animator[4]; + private final Animator[] mAnimators = new Animator[3]; private Launcher mLauncher; private Workspace mWorkspace; @@ -196,8 +195,6 @@ public class PinchAnimationManager { private void animateHotseatAndQsb(boolean show) { startAnimator(INDEX_HOTSEAT, mWorkspace.createHotseatAlphaAnimator(show ? 1 : 0), THRESHOLD_ANIM_DURATION); - startAnimator(INDEX_QSB, mWorkspace.mQsbAlphaController.animateAlphaAtIndex( - show ? 1 : 0, Workspace.QSB_ALPHA_INDEX_STATE_CHANGE), THRESHOLD_ANIM_DURATION); } private void animateOverviewPanelButtons(boolean show) { diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 61c970789..c2987f881 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -110,6 +110,9 @@ public final class Utilities { // An intent extra to indicate the horizontal scroll of the wallpaper. public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET"; + public static final int COLOR_EXTRACTION_JOB_ID = 1; + public static final int WALLPAPER_COMPAT_JOB_ID = 2; + // These values are same as that in {@link AsyncTask}. private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; @@ -549,6 +552,11 @@ public final class Utilities { LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE); } + public static SharedPreferences getDevicePrefs(Context context) { + return context.getSharedPreferences( + LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE); + } + public static boolean isPowerSaverOn(Context context) { PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); return powerManager.isPowerSaveMode(); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index ea4a662d3..3fe78757b 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -53,7 +53,6 @@ import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.widget.TextView; import android.widget.Toast; - import com.android.launcher3.Launcher.CustomContentCallbacks; import com.android.launcher3.Launcher.LauncherOverlay; import com.android.launcher3.UninstallDropTarget.DropTargetSource; @@ -80,14 +79,12 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LongArrayMap; -import com.android.launcher3.util.MultiStateAlphaController; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.VerticalFlingDetector; import com.android.launcher3.util.WallpaperOffsetInterpolator; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; - import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -111,7 +108,7 @@ public class Workspace extends PagedView * {@link #isFinishedSwitchingState()} ()} to return true. */ private static final float FINISHED_SWITCHING_STATE_TRANSITION_PROGRESS = 0.5f; - private static boolean ENFORCE_DRAG_EVENT_ORDER = false; + private static final boolean ENFORCE_DRAG_EVENT_ORDER = false; private static final int SNAP_OFF_EMPTY_SCREEN_DURATION = 400; private static final int FADE_EMPTY_SCREEN_DURATION = 150; @@ -137,8 +134,8 @@ public class Workspace extends PagedView private ShortcutAndWidgetContainer mDragSourceInternal; - @Thunk LongArrayMap<CellLayout> mWorkspaceScreens = new LongArrayMap<>(); - @Thunk ArrayList<Long> mScreenOrder = new ArrayList<Long>(); + @Thunk final LongArrayMap<CellLayout> mWorkspaceScreens = new LongArrayMap<>(); + @Thunk final ArrayList<Long> mScreenOrder = new ArrayList<>(); @Thunk Runnable mRemoveEmptyScreenRunnable; @Thunk boolean mDeferRemoveExtraEmptyScreen = false; @@ -174,7 +171,7 @@ public class Workspace extends PagedView */ private CellLayout mDropToLayout = null; - @Thunk Launcher mLauncher; + @Thunk final Launcher mLauncher; @Thunk DragController mDragController; // These are temporary variables to prevent having to allocate a new object just to @@ -183,10 +180,10 @@ public class Workspace extends PagedView private final int[] mTempXY = new int[2]; @Thunk float[] mDragViewVisualCenter = new float[2]; - private float[] mTempTouchCoordinates = new float[2]; + private final float[] mTempTouchCoordinates = new float[2]; private SpringLoadedDragController mSpringLoadedDragController; - private float mOverviewModeShrinkFactor; + private final float mOverviewModeShrinkFactor; // State variable that indicates whether the pages are small (ie when you're // in all apps or customize mode) @@ -226,21 +223,13 @@ public class Workspace extends PagedView /** * These values correspond to {@link Direction#X} & {@link Direction#Y} */ - private float[] mPageAlpha = new float[] {1, 1}; + private final float[] mPageAlpha = new float[] {1, 1}; /** * Hotseat alpha can be changed when moving horizontally, vertically, changing states. * The values correspond to {@link Direction#X}, {@link Direction#Y} & * {@link #HOTSEAT_STATE_ALPHA_INDEX} respectively. */ - private float[] mHotseatAlpha = new float[] {1, 1, 1}; - - public static final int QSB_ALPHA_INDEX_STATE_CHANGE = 0; - public static final int QSB_ALPHA_INDEX_Y_TRANSLATION = 1; - public static final int QSB_ALPHA_INDEX_PAGE_SCROLL = 2; - public static final int QSB_ALPHA_INDEX_OVERLAY_SCROLL = 3; - - - MultiStateAlphaController mQsbAlphaController; + private final float[] mHotseatAlpha = new float[] {1, 1, 1}; @ViewDebug.ExportedProperty(category = "launcher") private State mState = State.NORMAL; @@ -252,7 +241,7 @@ public class Workspace extends PagedView private boolean mStripScreensOnPageStopMoving = false; private DragPreviewProvider mOutlineProvider = null; - private boolean mWorkspaceFadeInAdjacentScreens; + private final boolean mWorkspaceFadeInAdjacentScreens; final WallpaperOffsetInterpolator mWallpaperOffset; private boolean mUnlockWallpaperFromDefaultPageOnLayout; @@ -297,7 +286,7 @@ public class Workspace extends PagedView @Thunk int mLastReorderY = -1; private SparseArray<Parcelable> mSavedStates; - private final ArrayList<Integer> mRestoredPages = new ArrayList<Integer>(); + private final ArrayList<Integer> mRestoredPages = new ArrayList<>(); private float mCurrentScale; private float mTransitionProgress; @@ -320,10 +309,9 @@ public class Workspace extends PagedView private boolean mIgnoreQsbScroll; // Handles workspace state transitions - private WorkspaceStateTransitionAnimation mStateTransitionAnimation; + private final WorkspaceStateTransitionAnimation mStateTransitionAnimation; private AccessibilityDelegate mPagesAccessibilityDelegate; - private OnStateChangeListener mOnStateChangeListener; /** * Used to inflate the Workspace from XML. @@ -378,10 +366,6 @@ public class Workspace extends PagedView } } - public void setOnStateChangeListener(OnStateChangeListener listener) { - mOnStateChangeListener = listener; - } - /** * Estimates the size of an item using spans: hSpan, vSpan. * @@ -536,7 +520,6 @@ public class Workspace extends PagedView public void initParentViews(View parent) { super.initParentViews(parent); mPageIndicator.setAccessibilityDelegate(new OverviewAccessibilityDelegate()); - mQsbAlphaController = new MultiStateAlphaController(mLauncher.getQsbContainer(), 4); } private int getDefaultPage() { @@ -576,11 +559,6 @@ public class Workspace extends PagedView return mTouchState != TOUCH_STATE_REST; } - private int getEmbeddedQsbId() { - return mLauncher.getDeviceProfile().isVerticalBarLayout() - ? R.id.qsb_container : R.id.workspace_blocked_row; - } - /** * Initializes and binds the first page * @param qsb an existing qsb to recycle or null. @@ -622,41 +600,17 @@ public class Workspace extends PagedView if (qsb == null) { // In transposed layout, we add the QSB in the Grid. As workspace does not touch the // edges, we do not need a full width QSB. - qsb = LayoutInflater.from(getContext()).inflate( - mLauncher.getDeviceProfile().isVerticalBarLayout() - ? R.layout.qsb_container : R.layout.qsb_blocker_view, - firstPage, false); + qsb = LayoutInflater.from(getContext()) + .inflate(R.layout.qsb_container,firstPage, false); } CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(), 1); lp.canReorder = false; - if (!firstPage.addViewToCellLayout(qsb, 0, getEmbeddedQsbId(), lp, true)) { + if (!firstPage.addViewToCellLayout(qsb, 0, R.id.qsb_container, lp, true)) { Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout"); } } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // Update the QSB to match the cell height. This is treating the QSB essentially as a child - // of workspace despite that it's not a true child. - // Note that it relies on the strict ordering of measuring the workspace before the QSB - // at the dragLayer level. - // Only measure the QSB when the view is enabled - if (FeatureFlags.QSB_ON_FIRST_SCREEN && getChildCount() > 0) { - CellLayout firstPage = (CellLayout) getChildAt(0); - int cellHeight = firstPage.getCellHeight(); - - View qsbContainer = mLauncher.getQsbContainer(); - ViewGroup.LayoutParams lp = qsbContainer.getLayoutParams(); - if (cellHeight > 0 && lp.height != cellHeight) { - lp.height = cellHeight; - qsbContainer.setLayoutParams(lp); - } - } - } - public void removeAllWorkspaceScreens() { // Disable all layout transitions before removing all pages to ensure that we don't get the // transition animations competing with us changing the scroll when we add pages or the @@ -670,7 +624,7 @@ public class Workspace extends PagedView } // Recycle the QSB widget - View qsb = findViewById(getEmbeddedQsbId()); + View qsb = findViewById(R.id.qsb_container); if (qsb != null) { ((ViewGroup) qsb.getParent()).removeView(qsb); } @@ -853,7 +807,7 @@ public class Workspace extends PagedView mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID); // Update the model if we have changed any screens - mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder); + LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder); } } @@ -955,7 +909,6 @@ public class Workspace extends PagedView return -1; } - int index = getPageIndexForScreenId(EXTRA_EMPTY_SCREEN_ID); CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID); mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID); mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID); @@ -967,7 +920,7 @@ public class Workspace extends PagedView mScreenOrder.add(newId); // Update the model for the new screen - mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder); + LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder); return newId; } @@ -1012,7 +965,7 @@ public class Workspace extends PagedView } int currentPage = getNextPage(); - ArrayList<Long> removeScreens = new ArrayList<Long>(); + ArrayList<Long> removeScreens = new ArrayList<>(); int total = mWorkspaceScreens.size(); for (int i = 0; i < total; i++) { long id = mWorkspaceScreens.keyAt(i); @@ -1056,7 +1009,7 @@ public class Workspace extends PagedView if (!removeScreens.isEmpty()) { // Update the model if we have changed any screens - mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder); + LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder); } if (pageShift >= 0) { @@ -1081,7 +1034,7 @@ public class Workspace extends PagedView /** * Adds the specified child in the specified screen based on the {@param info} - * See {@link #addInScreen}. + * See {@link #addInScreen(View, long, long, int, int, int, int)}. */ public void addInScreen(View child, ItemInfo info) { addInScreen(child, info.container, info.screenId, info.cellX, info.cellY, @@ -1406,17 +1359,9 @@ public class Workspace extends PagedView super.scrollTo(x, y); } - private void onWorkspaceOverallScrollChanged() { - if (!mIgnoreQsbScroll) { - mLauncher.getQsbContainer().setTranslationX( - mOverlayTranslation + mFirstPageScrollX - getScrollX()); - } - } - @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); - onWorkspaceOverallScrollChanged(); // Update the page indicator progress. boolean isTransitioning = mIsSwitchingState @@ -1497,9 +1442,6 @@ public class Workspace extends PagedView // device I've tried, translating the launcher causes things to get quite laggy. setWorkspaceTranslationAndAlpha(Direction.X, transX, alpha); setHotseatTranslationAndAlpha(Direction.X, transX, alpha); - onWorkspaceOverallScrollChanged(); - - mQsbAlphaController.setAlphaAtIndex(alpha, QSB_ALPHA_INDEX_OVERLAY_SCROLL); } /** @@ -1509,9 +1451,6 @@ public class Workspace extends PagedView */ public void setWorkspaceYTranslationAndAlpha(float translation, float alpha) { setWorkspaceTranslationAndAlpha(Direction.Y, translation, alpha); - - mLauncher.getQsbContainer().setTranslationY(translation); - mQsbAlphaController.setAlphaAtIndex(alpha, QSB_ALPHA_INDEX_Y_TRANSLATION); } /** @@ -1707,10 +1646,6 @@ public class Workspace extends PagedView float scrollProgress = getScrollProgress(screenCenter, child, i); float alpha = 1 - Math.abs(scrollProgress); child.getShortcutsAndWidgets().setAlpha(alpha); - - if (isQsbContainerPage(i)) { - mQsbAlphaController.setAlphaAtIndex(alpha, QSB_ALPHA_INDEX_PAGE_SCROLL); - } } } } @@ -1805,7 +1740,6 @@ public class Workspace extends PagedView } super.onLayout(changed, left, top, right, bottom); mFirstPageScrollX = getScrollForPage(0); - onWorkspaceOverallScrollChanged(); final LayoutTransition transition = getLayoutTransition(); // If the transition is running defer updating max scroll, as some empty pages could @@ -1827,7 +1761,6 @@ public class Workspace extends PagedView mIgnoreQsbScroll = false; transition.removeTransitionListener(this); mFirstPageScrollX = getScrollForPage(0); - onWorkspaceOverallScrollChanged(); } } }); @@ -1991,7 +1924,7 @@ public class Workspace extends PagedView mScreenOrder.add(getIdForScreen(cl)); } mLauncher.getUserEventDispatcher().logOverviewReorder(); - mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder); + LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder); // Re-enable auto layout transitions for page deletion. enableLayoutTransitions(); @@ -2070,10 +2003,6 @@ public class Workspace extends PagedView mLauncher.notifyWidgetProvidersChanged(); } - if (mOnStateChangeListener != null) { - mOnStateChangeListener.prepareStateChange(toState, animated ? workspaceAnim : null); - } - onPrepareStateTransition(mState.hasMultipleVisiblePages); StateTransitionListener listener = new StateTransitionListener(); @@ -2322,8 +2251,8 @@ public class Workspace extends PagedView mapPointFromSelfToChild(dropTargetLayout, mDragViewVisualCenter); } - int spanX = 1; - int spanY = 1; + int spanX; + int spanY; if (mDragInfo != null) { final CellLayout.CellInfo dragCellInfo = mDragInfo; spanX = dragCellInfo.spanX; @@ -3155,11 +3084,11 @@ public class Workspace extends PagedView } class FolderCreationAlarmListener implements OnAlarmListener { - CellLayout layout; - int cellX; - int cellY; + final CellLayout layout; + final int cellX; + final int cellY; - FolderIcon.PreviewBackground bg = new FolderIcon.PreviewBackground(); + final FolderIcon.PreviewBackground bg = new FolderIcon.PreviewBackground(); public FolderCreationAlarmListener(CellLayout layout, int cellX, int cellY) { this.layout = layout; @@ -3182,10 +3111,10 @@ public class Workspace extends PagedView } class ReorderAlarmListener implements OnAlarmListener { - float[] dragViewCenter; - int minSpanX, minSpanY, spanX, spanY; - DragObject dragObject; - View child; + final float[] dragViewCenter; + final int minSpanX, minSpanY, spanX, spanY; + final DragObject dragObject; + final View child; public ReorderAlarmListener(float[] dragViewCenter, int minSpanX, int minSpanY, int spanX, int spanY, DragObject dragObject, View child) { @@ -3277,7 +3206,7 @@ public class Workspace extends PagedView boolean findNearestVacantCell = true; if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) { - mTargetCell = findNearestArea((int) touchXY[0], (int) touchXY[1], spanX, spanY, + mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY, cellLayout, mTargetCell); float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell); @@ -3343,7 +3272,7 @@ public class Workspace extends PagedView animationStyle, finalView, true); } else { // This is for other drag/drop cases, like dragging from All Apps - View view = null; + View view; switch (info.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: @@ -3367,7 +3296,7 @@ public class Workspace extends PagedView // First we find the cell nearest to point at which the item is // dropped, without any consideration to whether there is an item there. if (touchXY != null) { - mTargetCell = findNearestArea((int) touchXY[0], (int) touchXY[1], spanX, spanY, + mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY, cellLayout, mTargetCell); float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell); @@ -3616,7 +3545,7 @@ public class Workspace extends PagedView } else if (FeatureFlags.IS_DOGFOOD_BUILD) { throw new RuntimeException("Invalid state: cellLayout == null in " + "Workspace#onDropCompleted. Please file a bug. "); - }; + } } if ((d.cancelled || (beingCalledAfterUninstall && !mUninstallSuccessful)) && mDragInfo.cell != null) { @@ -3768,7 +3697,7 @@ public class Workspace extends PagedView * Returns a list of all the CellLayouts in the workspace. */ ArrayList<CellLayout> getWorkspaceAndHotseatCellLayouts() { - ArrayList<CellLayout> layouts = new ArrayList<CellLayout>(); + ArrayList<CellLayout> layouts = new ArrayList<>(); int screenCount = getChildCount(); for (int screen = 0; screen < screenCount; screen++) { layouts.add(((CellLayout) getChildAt(screen))); @@ -3910,7 +3839,7 @@ public class Workspace extends PagedView * @param view view for the shortcut * @return true if done, false to continue the map */ - public boolean evaluate(ItemInfo info, View view); + boolean evaluate(ItemInfo info, View view); } /** @@ -3952,7 +3881,7 @@ public class Workspace extends PagedView void updateShortcuts(ArrayList<ShortcutInfo> shortcuts) { int total = shortcuts.size(); - final HashSet<ShortcutInfo> updates = new HashSet<ShortcutInfo>(total); + final HashSet<ShortcutInfo> updates = new HashSet<>(total); final HashSet<Long> folderIds = new HashSet<>(); for (int i = 0; i < total; i++) { @@ -4230,20 +4159,6 @@ public class Workspace extends PagedView } } - public interface OnStateChangeListener { - - /** - * Called when the workspace state is changing. - * @param toState final state - * @param targetAnim animation which will be played during the transition or null. - */ - void prepareStateChange(State toState, AnimatorSet targetAnim); - } - - public static final boolean isQsbContainerPage(int pageNo) { - return pageNo == 0; - } - private class StateTransitionListener extends AnimatorListenerAdapter implements AnimatorUpdateListener { @Override diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 482a2c93b..32deaf286 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -355,27 +355,10 @@ public class WorkspaceStateTransitionAnimation { cl.setBackgroundAlpha(finalBackgroundAlpha); cl.setShortcutAndWidgetAlpha(finalAlpha); } - - if (Workspace.isQsbContainerPage(i) && - states.stateIsNormal && mWorkspaceFadeInAdjacentScreens) { - if (animated) { - Animator anim = mWorkspace.mQsbAlphaController - .animateAlphaAtIndex(finalAlpha, Workspace.QSB_ALPHA_INDEX_PAGE_SCROLL); - anim.setDuration(duration); - anim.setInterpolator(mZoomInInterpolator); - mStateAnimator.play(anim); - } else { - mWorkspace.mQsbAlphaController.setAlphaAtIndex( - finalAlpha, Workspace.QSB_ALPHA_INDEX_PAGE_SCROLL); - } - } } final ViewGroup overviewPanel = mLauncher.getOverviewPanel(); - Animator qsbAlphaAnimation = mWorkspace.mQsbAlphaController - .animateAlphaAtIndex(finalQsbAlpha, Workspace.QSB_ALPHA_INDEX_STATE_CHANGE); - if (animated) { Animator scale = LauncherAnimUtils.ofPropertyValuesHolder(mWorkspace, new PropertyListBuilder().scale(mNewScale) @@ -393,7 +376,6 @@ public class WorkspaceStateTransitionAnimation { // For animation optimization, we may need to provide the Launcher transition // with a set of views on which to force build and manage layers in certain scenarios. layerViews.addView(overviewPanel); - layerViews.addView(mLauncher.getQsbContainer()); layerViews.addView(mLauncher.getHotseat()); layerViews.addView(mWorkspace.getPageIndicator()); @@ -407,11 +389,9 @@ public class WorkspaceStateTransitionAnimation { overviewPanelAlpha.setDuration(duration); hotseatAlpha.setDuration(duration); - qsbAlphaAnimation.setDuration(duration); mStateAnimator.play(overviewPanelAlpha); mStateAnimator.play(hotseatAlpha); - mStateAnimator.play(qsbAlphaAnimation); mStateAnimator.addListener(new AnimatorListenerAdapter() { boolean canceled = false; @Override @@ -439,7 +419,6 @@ public class WorkspaceStateTransitionAnimation { AlphaUpdateListener.updateVisibility(overviewPanel, accessibilityEnabled); mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded); - qsbAlphaAnimation.end(); mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha).end(); mWorkspace.updateCustomContentVisibility(); mWorkspace.setScaleX(mNewScale); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index a399d748a..c3df07360 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -20,7 +20,6 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.InsetDrawable; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.Selection; @@ -92,9 +91,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc mLauncher = Launcher.getLauncher(context); mApps = new AlphabeticalAppsList(context); - mSpringAnimationHandler = new SpringAnimationHandler(SpringAnimationHandler.Y_DIRECTION); - mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this, - mSpringAnimationHandler); + mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this); + mSpringAnimationHandler = mAdapter.getSpringAnimationHandler(); mApps.setAdapter(mAdapter); mLayoutManager = mAdapter.getLayoutManager(); mSearchQueryBuilder = new SpannableStringBuilder(); @@ -426,8 +424,11 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - if (mScrollState == RecyclerView.SCROLL_STATE_DRAGGING) { - mSpringAnimationHandler.skipToEnd(); + if (mScrollState == RecyclerView.SCROLL_STATE_DRAGGING + || (dx == 0 && dy == 0)) { + if (mSpringAnimationHandler.isRunning()){ + mSpringAnimationHandler.skipToEnd(); + } return; } @@ -436,7 +437,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc // We only show the spring animation when at the top or bottom, so we wait until the // first or last row is visible to ensure that all animations run in sync. - if (first == 0 || last >= mAdapter.getItemCount() - mAdapter.getNumAppsPerRow()) { + if ((first == 0 && dy < 0) || (last == mAdapter.getItemCount() - 1 && dy > 0)) { mSpringAnimationHandler.animateToFinalPosition(0); } } diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index d3d23ca24..9c7372f2c 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -19,6 +19,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Point; +import android.support.animation.DynamicAnimation; import android.support.animation.SpringAnimation; import android.support.v4.view.accessibility.AccessibilityEventCompat; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; @@ -38,6 +39,7 @@ import com.android.launcher3.AppInfo; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Launcher; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem; import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.config.FeatureFlags; @@ -96,11 +98,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. */ public static class ViewHolder extends RecyclerView.ViewHolder { - /** - * Springs used for items where isViewType(viewType, VIEW_TYPE_MASK_HAS_SPRINGS) is true. - */ - private SpringAnimation spring; - public ViewHolder(View v) { super(v); } @@ -213,11 +210,10 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. // The intent to send off to the market app, updated each time the search query changes. private Intent mMarketSearchIntent; - private SpringAnimationHandler mSpringAnimationHandler; + private SpringAnimationHandler<ViewHolder> mSpringAnimationHandler; public AllAppsGridAdapter(Launcher launcher, AlphabeticalAppsList apps, View.OnClickListener - iconClickListener, View.OnLongClickListener iconLongClickListener, - SpringAnimationHandler springAnimationHandler) { + iconClickListener, View.OnLongClickListener iconLongClickListener) { Resources res = launcher.getResources(); mLauncher = launcher; mApps = apps; @@ -228,7 +224,14 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. mLayoutInflater = LayoutInflater.from(launcher); mIconClickListener = iconClickListener; mIconLongClickListener = iconLongClickListener; - mSpringAnimationHandler = springAnimationHandler; + if (FeatureFlags.LAUNCHER3_PHYSICS) { + mSpringAnimationHandler = new SpringAnimationHandler<>( + SpringAnimationHandler.Y_DIRECTION, new AllAppsSpringAnimationFactory()); + } + } + + public SpringAnimationHandler getSpringAnimationHandler() { + return mSpringAnimationHandler; } public static boolean isDividerViewType(int viewType) { @@ -292,8 +295,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. R.layout.all_apps_icon, parent, false); icon.setOnClickListener(mIconClickListener); icon.setOnLongClickListener(mIconLongClickListener); - icon.setLongPressTimeout(ViewConfiguration.get(parent.getContext()) - .getLongPressTimeout()); + icon.setLongPressTimeout(ViewConfiguration.getLongPressTimeout()); icon.setOnFocusChangeListener(mIconFocusListener); // Ensure the all apps icon height matches the workspace icons @@ -386,8 +388,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. public void onViewAttachedToWindow(ViewHolder holder) { int type = holder.getItemViewType(); if (FeatureFlags.LAUNCHER3_PHYSICS && isViewType(type, VIEW_TYPE_MASK_HAS_SPRINGS)) { - holder.spring = mSpringAnimationHandler.add(holder.itemView, - holder.getAdapterPosition(), mApps, mAppsPerRow, holder.spring); + mSpringAnimationHandler.add(holder.itemView, holder); } } @@ -395,7 +396,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. public void onViewDetachedFromWindow(ViewHolder holder) { int type = holder.getItemViewType(); if (FeatureFlags.LAUNCHER3_PHYSICS && isViewType(type, VIEW_TYPE_MASK_HAS_SPRINGS)) { - holder.spring = mSpringAnimationHandler.remove(holder.spring); + mSpringAnimationHandler.remove(holder.itemView); } } @@ -415,4 +416,121 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter. AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(position); return item.viewType; } + + /** + * Helper class to set the SpringAnimation values for an item in the adapter. + */ + private class AllAppsSpringAnimationFactory + implements SpringAnimationHandler.AnimationFactory<ViewHolder> { + private static final float DEFAULT_MAX_VALUE_PX = 100; + private static final float DEFAULT_MIN_VALUE_PX = -DEFAULT_MAX_VALUE_PX; + + // Damping ratio range is [0, 1] + private static final float SPRING_DAMPING_RATIO = 0.55f; + + // Stiffness is a non-negative number. + private static final float MIN_SPRING_STIFFNESS = 580f; + private static final float MAX_SPRING_STIFFNESS = 900f; + + // The amount by which each adjacent rows' stiffness will differ. + private static final float ROW_STIFFNESS_COEFFICIENT = 50f; + + @Override + public SpringAnimation initialize(ViewHolder vh) { + return SpringAnimationHandler.forView(vh.itemView, DynamicAnimation.TRANSLATION_Y, 0); + } + + /** + * @param spring A new or recycled SpringAnimation. + * @param vh The ViewHolder that {@param spring} is related to. + */ + @Override + public void update(SpringAnimation spring, ViewHolder vh) { + int numPredictedApps = Math.min(mAppsPerRow, mApps.getPredictedApps().size()); + int appPosition = getAppPosition(vh.getAdapterPosition(), numPredictedApps, + mAppsPerRow); + + int col = appPosition % mAppsPerRow; + int row = appPosition / mAppsPerRow; + + int numTotalRows = mApps.getNumAppRows() - 1; // zero-based count + if (row > (numTotalRows / 2)) { + // Mirror the rows so that the top row acts the same as the bottom row. + row = Math.abs(numTotalRows - row); + } + + // We manipulate the stiffness, min, and max values based on the items distance to the + // first row and the items distance to the center column to create the ^-shaped motion + // effect. + float rowFactor = (1 + row) * 0.5f; + float colFactor = getColumnFactor(col, mAppsPerRow); + + float minValue = DEFAULT_MIN_VALUE_PX * (rowFactor + colFactor); + float maxValue = DEFAULT_MAX_VALUE_PX * (rowFactor + colFactor); + + float stiffness = Utilities.boundToRange( + MAX_SPRING_STIFFNESS - (row * ROW_STIFFNESS_COEFFICIENT), + MIN_SPRING_STIFFNESS, + MAX_SPRING_STIFFNESS); + + spring.setMinValue(minValue) + .setMaxValue(maxValue) + .getSpring() + .setStiffness(stiffness) + .setDampingRatio(SPRING_DAMPING_RATIO); + } + + /** + * @return The app position is the position of the app in the Adapter if we ignored all + * other view types. + * + * The first app is at position 0, and the first app each following row is at a + * position that is a multiple of {@param appsPerRow}. + * + * ie. If there are 5 apps per row, and there are two rows of apps: + * 0 1 2 3 4 + * 5 6 7 8 9 + */ + private int getAppPosition(int position, int numPredictedApps, int appsPerRow) { + int appPosition = position; + int numDividerViews = 1 + (numPredictedApps == 0 ? 0 : 1); + + int allAppsStartAt = numDividerViews + numPredictedApps; + if (numDividerViews == 1 || position < allAppsStartAt) { + appPosition -= 1; + } else { + // We cannot assume that the predicted row will always be full. + int numPredictedAppsOffset = appsPerRow - numPredictedApps; + appPosition = position + numPredictedAppsOffset - numDividerViews; + } + + return appPosition; + } + + /** + * Increase the column factor as the distance increases between the column and the center + * column(s). + */ + private float getColumnFactor(int col, int numCols) { + float centerColumn = numCols / 2; + int distanceToCenter = (int) Math.abs(col - centerColumn); + + boolean evenNumberOfColumns = numCols % 2 == 0; + if (evenNumberOfColumns && col < centerColumn) { + distanceToCenter -= 1; + } + + float factor = 0; + while (distanceToCenter > 0) { + if (distanceToCenter == 1) { + factor += 0.2f; + } else { + factor += 0.1f; + } + --distanceToCenter; + } + + return factor; + } + } } diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index d76abccd3..b2a74ff15 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -97,6 +97,10 @@ public class AllAppsRecyclerView extends BaseRecyclerView { mFastScrollHelper = new AllAppsFastScrollHelper(this, apps); } + public AlphabeticalAppsList getApps() { + return mApps; + } + /** * Sets the number of apps per row in this recycler view. */ diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index ba20135be..d79b0d19d 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -71,6 +71,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private final VerticalPullDetector mDetector; private final ArgbEvaluator mEvaluator; private final boolean mIsDarkTheme; + private final boolean mIsWorkspaceDarkText; // Animation in this class is controlled by a single variable {@link mProgress}. // Visually, it represents top y coordinate of the all apps container if multiplied with @@ -112,7 +113,8 @@ public class AllAppsTransitionController implements TouchController, VerticalPul mEvaluator = new ArgbEvaluator(); mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary); - mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isPrimaryColorDark); + mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark); + mIsWorkspaceDarkText = Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText); } @Override @@ -281,7 +283,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private void updateLightStatusBar(float shift) { // Do not modify status bar in dark theme or on landscape as all apps is not full bleed. - if (mIsDarkTheme || (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS + if (mIsDarkTheme || mIsWorkspaceDarkText || (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS && mLauncher.getDeviceProfile().isVerticalBarLayout())) { return; } diff --git a/src/com/android/launcher3/anim/AnimationLayerSet.java b/src/com/android/launcher3/anim/AnimationLayerSet.java index 14bcd1718..f0b34587a 100644 --- a/src/com/android/launcher3/anim/AnimationLayerSet.java +++ b/src/com/android/launcher3/anim/AnimationLayerSet.java @@ -18,9 +18,8 @@ package com.android.launcher3.anim; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.util.ArrayMap; import android.view.View; - -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -29,14 +28,14 @@ import java.util.Map; */ public class AnimationLayerSet extends AnimatorListenerAdapter { - private final HashMap<View, Integer> mViewsToLayerTypeMap; + private final ArrayMap<View, Integer> mViewsToLayerTypeMap; public AnimationLayerSet() { - mViewsToLayerTypeMap = new HashMap<>(); + mViewsToLayerTypeMap = new ArrayMap<>(); } public AnimationLayerSet(View v) { - mViewsToLayerTypeMap = new HashMap<>(1); + mViewsToLayerTypeMap = new ArrayMap<>(1); addView(v); } diff --git a/src/com/android/launcher3/anim/SpringAnimationHandler.java b/src/com/android/launcher3/anim/SpringAnimationHandler.java index 488657c36..038f82682 100644 --- a/src/com/android/launcher3/anim/SpringAnimationHandler.java +++ b/src/com/android/launcher3/anim/SpringAnimationHandler.java @@ -15,7 +15,7 @@ */ package com.android.launcher3.anim; -import android.support.animation.DynamicAnimation; +import android.support.animation.FloatPropertyCompat; import android.support.animation.SpringAnimation; import android.support.animation.SpringForce; import android.support.annotation.IntDef; @@ -24,8 +24,7 @@ import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; -import com.android.launcher3.Utilities; -import com.android.launcher3.allapps.AlphabeticalAppsList; +import com.android.launcher3.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -35,77 +34,67 @@ import java.util.ArrayList; * Handler class that manages springs for a set of views that should all move based on the same * {@link MotionEvent}s. * - * Supports using physics for X or Y translations. + * Supports setting either X or Y velocity on the list of springs added to this handler. */ -public class SpringAnimationHandler { +public class SpringAnimationHandler<T> { private static final String TAG = "SpringAnimationHandler"; private static final boolean DEBUG = false; - private static final float DEFAULT_MAX_VALUE = 100; - private static final float DEFAULT_MIN_VALUE = -DEFAULT_MAX_VALUE; - - private static final float SPRING_DAMPING_RATIO = 0.55f; - private static final float MIN_SPRING_STIFFNESS = 580f; - private static final float MAX_SPRING_STIFFNESS = 900f; + private static final float VELOCITY_DAMPING_FACTOR = 0.175f; @Retention(RetentionPolicy.SOURCE) @IntDef({Y_DIRECTION, X_DIRECTION}) public @interface Direction {} public static final int Y_DIRECTION = 0; public static final int X_DIRECTION = 1; - private int mDirection; + private int mVelocityDirection; private VelocityTracker mVelocityTracker; private float mCurrentVelocity = 0; private boolean mShouldComputeVelocity = false; + private AnimationFactory<T> mAnimationFactory; + private ArrayList<SpringAnimation> mAnimations = new ArrayList<>(); - public SpringAnimationHandler(@Direction int direction) { - mDirection = direction; - mVelocityTracker = VelocityTracker.obtain(); + /** + * @param direction Either {@link #X_DIRECTION} or {@link #Y_DIRECTION}. + * Determines which direction we use to calculate and set the velocity. + * @param factory The AnimationFactory is responsible for initializing and updating the + * SpringAnimations added to this class. + */ + public SpringAnimationHandler(@Direction int direction, AnimationFactory<T> factory) { + mVelocityDirection = direction; + mAnimationFactory = factory; } - public SpringAnimation add(View view, int position, AlphabeticalAppsList apps, int appsPerRow, - SpringAnimation recycle) { - int numPredictedApps = Math.min(appsPerRow, apps.getPredictedApps().size()); - int appPosition = getAppPosition(position, numPredictedApps, appsPerRow); - - int col = appPosition % appsPerRow; - int row = appPosition / appsPerRow; - - int numTotalRows = apps.getNumAppRows() - 1; // zero offset - if (row > (numTotalRows / 2)) { - // Mirror the rows so that the top row acts the same as the bottom row. - row = Math.abs(numTotalRows - row); + /** + * Adds a new or recycled animation to the list of springs handled by this class. + * + * @param view The view the spring is attached to. + * @param object Used to initialize and update the spring. + */ + public void add(View view, T object) { + SpringAnimation spring = (SpringAnimation) view.getTag(R.id.spring_animation_tag); + if (spring == null) { + spring = mAnimationFactory.initialize(object); + view.setTag(R.id.spring_animation_tag, spring); } - - // We manipulate the stiffness, min, and max values based on the items distance to the first - // row and the items distance to the center column to create the ^-shaped motion effect. - float rowFactor = (1 + row) * 0.5f; - float colFactor = getColumnFactor(col, appsPerRow); - - float minValue = DEFAULT_MIN_VALUE * (rowFactor + colFactor); - float maxValue = DEFAULT_MAX_VALUE * (rowFactor + colFactor); - - float stiffness = Utilities.boundToRange(MAX_SPRING_STIFFNESS - (row * 50f), - MIN_SPRING_STIFFNESS, MAX_SPRING_STIFFNESS); - - SpringAnimation animation = (recycle != null ? recycle : createSpringAnimation(view)) - .setStartVelocity(mCurrentVelocity) - .setMinValue(minValue) - .setMaxValue(maxValue); - animation.getSpring().setStiffness(stiffness); - - mAnimations.add(animation); - return animation; + mAnimationFactory.update(spring, object); + spring.setStartVelocity(mCurrentVelocity); + mAnimations.add(spring); } - public SpringAnimation remove(SpringAnimation animation) { - animation.skipToEnd(); + /** + * Stops and removes the spring attached to {@param view}. + */ + public void remove(View view) { + SpringAnimation animation = (SpringAnimation) view.getTag(R.id.spring_animation_tag); + if (animation.canSkipToEnd()) { + animation.skipToEnd(); + } mAnimations.remove(animation); - return animation; } public void addMovement(MotionEvent event) { @@ -138,13 +127,20 @@ public class SpringAnimationHandler { reset(); } + public boolean isRunning() { + // All the animations run at the same time so we can just check the first one. + return !mAnimations.isEmpty() && mAnimations.get(0).isRunning(); + } + public void skipToEnd() { if (DEBUG) Log.d(TAG, "setStartVelocity#skipToEnd"); if (DEBUG) Log.v(TAG, "setStartVelocity#skipToEnd", new Exception()); int size = mAnimations.size(); for (int i = 0; i < size; ++i) { - mAnimations.get(i).skipToEnd(); + if (mAnimations.get(i).canSkipToEnd()) { + mAnimations.get(i).skipToEnd(); + } } } @@ -164,84 +160,55 @@ public class SpringAnimationHandler { } private void computeVelocity() { - getVelocityTracker().computeCurrentVelocity(175); + getVelocityTracker().computeCurrentVelocity(1000 /* millis */); mCurrentVelocity = isVerticalDirection() ? getVelocityTracker().getYVelocity() : getVelocityTracker().getXVelocity(); + mCurrentVelocity *= VELOCITY_DAMPING_FACTOR; mShouldComputeVelocity = false; if (DEBUG) Log.d(TAG, "computeVelocity=" + mCurrentVelocity); } private boolean isVerticalDirection() { - return mDirection == Y_DIRECTION; + return mVelocityDirection == Y_DIRECTION; } - private SpringAnimation createSpringAnimation(View view) { - DynamicAnimation.ViewProperty property = isVerticalDirection() - ? DynamicAnimation.TRANSLATION_Y - : DynamicAnimation.TRANSLATION_X; - - return new SpringAnimation(view, property, 0) - .setStartValue(1f) - .setSpring(new SpringForce(0) - .setDampingRatio(SPRING_DAMPING_RATIO)); + private VelocityTracker getVelocityTracker() { + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } + return mVelocityTracker; } /** - * @return The app position is the position of the app in the Adapter if we ignored all other - * view types. + * This interface is used to initialize and update the SpringAnimations added to the + * {@link SpringAnimationHandler}. * - * ie. The first predicted app is at position 0, and the first app of all apps is - * at {@param appsPerRow}. + * @param <T> The object that each SpringAnimation is attached to. */ - private int getAppPosition(int position, int numPredictedApps, int appsPerRow) { - int appPosition = position; - int numDividerViews = 1 + (numPredictedApps == 0 ? 0 : 1); - - int allAppsStartAt = numDividerViews + numPredictedApps; - if (numDividerViews == 1 || position < allAppsStartAt) { - appPosition -= 1; - } else { - // We cannot assume that the predicted row will always be full. - int numPredictedAppsOffset = appsPerRow - numPredictedApps; - appPosition = position + numPredictedAppsOffset - numDividerViews; - } + public interface AnimationFactory<T> { + + /** + * Initializes a new Spring for {@param object}. + */ + SpringAnimation initialize(T object); - return appPosition; + /** + * Updates the value of {@param spring} based on {@param object}. + */ + void update(SpringAnimation spring, T object); } /** - * Increase the column factor as the distance increases between the column and the center - * column(s). + * Helper method to create a new SpringAnimation for {@param view}. */ - private float getColumnFactor(int col, int numCols) { - float centerColumn = numCols / 2; - int distanceToCenter = (int) Math.abs(col - centerColumn); - - boolean evenNumberOfColumns = numCols % 2 == 0; - if (evenNumberOfColumns && col < centerColumn) { - distanceToCenter -= 1; - } - - float factor = 0; - while (distanceToCenter > 0) { - if (distanceToCenter == 1) { - factor += 0.2f; - } else { - factor += 0.1f; - } - --distanceToCenter; - } - - return factor; + public static SpringAnimation forView(View view, FloatPropertyCompat property, float finalPos) { + SpringAnimation spring = new SpringAnimation(view, property, finalPos); + spring.setStartValue(1f); + spring.setSpring(new SpringForce(finalPos)); + return spring; } - private VelocityTracker getVelocityTracker() { - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - return mVelocityTracker; - } } diff --git a/src/com/android/launcher3/badge/BadgeRenderer.java b/src/com/android/launcher3/badge/BadgeRenderer.java index adde4a2fc..ba1977af4 100644 --- a/src/com/android/launcher3/badge/BadgeRenderer.java +++ b/src/com/android/launcher3/badge/BadgeRenderer.java @@ -63,7 +63,6 @@ public class BadgeRenderer { private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); private final SparseArray<Bitmap> mBackgroundsWithShadow; - private final IconPalette mIconPalette; public BadgeRenderer(Context context, int iconSizePx) { mContext = context; @@ -83,25 +82,24 @@ public class BadgeRenderer { mTextHeight = tempTextHeight.height(); mBackgroundsWithShadow = new SparseArray<>(3); - - mIconPalette = IconPalette.fromDominantColor(context.getColor(R.color.badge_color)); } /** * Draw a circle in the top right corner of the given bounds, and draw * {@link BadgeInfo#getNotificationCount()} on top of the circle. + * @param palette The colors (based on the icon) to use for the badge. * @param badgeInfo Contains data to draw on the badge. Could be null if we are animating out. * @param iconBounds The bounds of the icon being badged. * @param badgeScale The progress of the animation, from 0 to 1. * @param spaceForOffset How much space is available to offset the badge up and to the right. */ - public void draw(Canvas canvas, @Nullable BadgeInfo badgeInfo, + public void draw(Canvas canvas, IconPalette palette, @Nullable BadgeInfo badgeInfo, Rect iconBounds, float badgeScale, Point spaceForOffset) { - mTextPaint.setColor(mIconPalette.textColor); + mTextPaint.setColor(palette.textColor); IconDrawer iconDrawer = badgeInfo != null && badgeInfo.isIconLarge() ? mLargeIconDrawer : mSmallIconDrawer; Shader icon = badgeInfo == null ? null : badgeInfo.getNotificationIconForBadge( - mContext, mIconPalette.backgroundColor, mSize, iconDrawer.mPadding); + mContext, palette.backgroundColor, mSize, iconDrawer.mPadding); String notificationCount = badgeInfo == null ? "0" : String.valueOf(badgeInfo.getNotificationCount()); int numChars = notificationCount.length(); @@ -127,7 +125,7 @@ public class BadgeRenderer { canvas.translate(badgeCenterX + offsetX, badgeCenterY - offsetY); canvas.scale(badgeScale, badgeScale); // Prepare the background and shadow and possible stacking effect. - mBackgroundPaint.setColorFilter(mIconPalette.backgroundColorMatrixFilter); + mBackgroundPaint.setColorFilter(palette.backgroundColorMatrixFilter); int backgroundWithShadowSize = backgroundWithShadow.getHeight(); // Same as width. boolean shouldStack = !isDot && badgeInfo != null && badgeInfo.getNotificationKeys().size() > 1; @@ -149,7 +147,7 @@ public class BadgeRenderer { -backgroundWithShadowSize / 2, mBackgroundPaint); iconDrawer.drawIcon(icon, canvas); } else if (isDot) { - mBackgroundPaint.setColorFilter(mIconPalette.saturatedBackgroundColorMatrixFilter); + mBackgroundPaint.setColorFilter(palette.saturatedBackgroundColorMatrixFilter); canvas.drawBitmap(backgroundWithShadow, -backgroundWithShadowSize / 2, -backgroundWithShadowSize / 2, mBackgroundPaint); } diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java index 26f4ae721..75a2a5d18 100644 --- a/src/com/android/launcher3/compat/LauncherAppsCompat.java +++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java @@ -25,11 +25,9 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; import android.support.annotation.Nullable; - import com.android.launcher3.Utilities; import com.android.launcher3.shortcuts.ShortcutInfoCompat; import com.android.launcher3.util.PackageUserKey; - import java.util.List; public abstract class LauncherAppsCompat { @@ -50,7 +48,7 @@ public abstract class LauncherAppsCompat { } private static LauncherAppsCompat sInstance; - private static Object sInstanceLock = new Object(); + private static final Object sInstanceLock = new Object(); public static LauncherAppsCompat getInstance(Context context) { synchronized (sInstanceLock) { diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java b/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java index 34316644a..8bdcedbbc 100644 --- a/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java +++ b/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java @@ -17,31 +17,36 @@ package com.android.launcher3.compat; import static android.app.WallpaperManager.FLAG_SYSTEM; -import android.app.IntentService; +import static com.android.launcher3.Utilities.getDevicePrefs; + import android.app.WallpaperInfo; import android.app.WallpaperManager; +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.os.Bundle; import android.os.Handler; +import android.os.HandlerThread; import android.os.ParcelFileDescriptor; -import android.os.ResultReceiver; import android.support.annotation.Nullable; import android.support.v7.graphics.Palette; import android.util.Log; import android.util.Pair; import android.util.SparseIntArray; -import com.android.launcher3.LauncherFiles; import com.android.launcher3.Utilities; import java.io.IOException; @@ -53,7 +58,8 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat { private static final String VERSION_PREFIX = "1,"; private static final String KEY_COLORS = "wallpaper_parsed_colors"; - private static final String EXTRA_RECEIVER = "receiver"; + private static final String ACTION_EXTRACTION_COMPLETE = + "com.android.launcher3.compat.WallpaperManagerCompatVL.EXTRACTION_COMPLETE"; private final ArrayList<OnColorsChangedListenerCompat> mListeners = new ArrayList<>(); @@ -63,7 +69,7 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat { WallpaperManagerCompatVL(Context context) { mContext = context; - String colors = prefs(mContext).getString(KEY_COLORS, ""); + String colors = getDevicePrefs(mContext).getString(KEY_COLORS, ""); int wallpaperId = -1; if (colors.startsWith(VERSION_PREFIX)) { Pair<Integer, WallpaperColorsCompat> storedValue = parseValue(colors); @@ -80,6 +86,28 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat { reloadColors(); } }, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); + + // Register a receiver for results + String permission = null; + // Find a permission which only we can use. + try { + for (PermissionInfo info : context.getPackageManager().getPackageInfo( + context.getPackageName(), + PackageManager.GET_PERMISSIONS).permissions) { + if ((info.protectionLevel & PermissionInfo.PROTECTION_SIGNATURE) != 0) { + permission = info.name; + } + } + } catch (PackageManager.NameNotFoundException e) { + // Something went wrong. ignore + Log.d(TAG, "Unable to get permission info", e); + } + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + handleResult(intent.getStringExtra(KEY_COLORS)); + } + }, new IntentFilter(ACTION_EXTRACTION_COMPLETE), permission, new Handler()); } @Nullable @@ -94,30 +122,20 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat { } private void reloadColors() { - ResultReceiver receiver = new ResultReceiver(new Handler()) { - - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - handleResult(resultData.getString(KEY_COLORS)); - } - }; - mContext.startService(new Intent(mContext, ColorExtractionService.class) - .putExtra(EXTRA_RECEIVER, receiver)); + JobInfo job = new JobInfo.Builder(Utilities.WALLPAPER_COMPAT_JOB_ID, + new ComponentName(mContext, ColorExtractionService.class)) + .setMinimumLatency(0).build(); + ((JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(job); } private void handleResult(String result) { - prefs(mContext).edit().putString(KEY_COLORS, result).apply(); + getDevicePrefs(mContext).edit().putString(KEY_COLORS, result).apply(); mColorsCompat = parseValue(result).second; for (OnColorsChangedListenerCompat listener : mListeners) { listener.onColorsChanged(mColorsCompat, FLAG_SYSTEM); } } - private static SharedPreferences prefs(Context context) { - return context.getSharedPreferences( - LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE); - } - private static final int getWallpaperId(Context context) { if (!Utilities.ATLEAST_NOUGAT) { return -1; @@ -146,18 +164,43 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat { /** * Intent service to handle color extraction */ - public static class ColorExtractionService extends IntentService { + public static class ColorExtractionService extends JobService implements Runnable { private static final int MAX_WALLPAPER_EXTRACTION_AREA = 112 * 112; - public ColorExtractionService() { - super("ColorExtractionService"); + private HandlerThread mWorkerThread; + private Handler mWorkerHandler; + + @Override + public void onCreate() { + super.onCreate(); + mWorkerThread = new HandlerThread("ColorExtractionService"); + mWorkerThread.start(); + mWorkerHandler = new Handler(mWorkerThread.getLooper()); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mWorkerThread.quit(); + } + + @Override + public boolean onStartJob(final JobParameters jobParameters) { + mWorkerHandler.post(this); + return true; + } + + @Override + public boolean onStopJob(JobParameters jobParameters) { + mWorkerHandler.removeCallbacksAndMessages(null); + return true; } /** * Extracts the wallpaper colors and sends the result back through the receiver. */ @Override - protected void onHandleIntent(@Nullable Intent intent) { + public void run() { int wallpaperId = getWallpaperId(this); Bitmap bitmap = null; @@ -228,10 +271,10 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat { value = builder.toString(); } - ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RECEIVER); - Bundle result = new Bundle(); - result.putString(KEY_COLORS, value); - receiver.send(0, result); + // Send the result + sendBroadcast(new Intent(ACTION_EXTRACTION_COMPLETE) + .setPackage(getPackageName()) + .putExtra(KEY_COLORS, value)); } } } diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 7178c5e8d..be5f01adb 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -27,6 +27,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.Region; +import android.support.v4.graphics.ColorUtils; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -54,10 +55,12 @@ import com.android.launcher3.ShortcutAndWidgetContainer; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.dynamicui.WallpaperColorInfo; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.logging.LoggerUtils; +import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.TouchController; import com.android.launcher3.widget.WidgetsBottomSheet; @@ -72,9 +75,6 @@ public class DragLayer extends InsettableFrameLayout { public static final int ANIMATION_END_DISAPPEAR = 0; public static final int ANIMATION_END_REMAIN_VISIBLE = 2; - // Scrim color without any alpha component. - private static final int SCRIM_COLOR = Color.BLACK & 0x00FFFFFF; - private final int[] mTmpXY = new int[2]; @Thunk DragController mDragController; @@ -107,6 +107,7 @@ public class DragLayer extends InsettableFrameLayout { // Related to adjacent page hints private final Rect mScrollChildPosition = new Rect(); private final ViewGroupFocusHelper mFocusIndicatorHelper; + private final WallpaperColorInfo mWallpaperColorInfo; // Related to pinch-to-go-to-overview gesture. private PinchToOverviewListener mPinchListener = null; @@ -130,6 +131,7 @@ public class DragLayer extends InsettableFrameLayout { mIsRtl = Utilities.isRtl(getResources()); mFocusIndicatorHelper = new ViewGroupFocusHelper(this); + mWallpaperColorInfo = WallpaperColorInfo.getInstance(getContext()); } public void setup(Launcher launcher, DragController dragController, @@ -451,7 +453,8 @@ public class DragLayer extends InsettableFrameLayout { @Override public void setInsets(Rect insets) { super.setInsets(insets); - setBackgroundResource(insets.top == 0 ? 0 : R.drawable.workspace_bg); + setBackground(insets.top == 0 ? null + : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim)); } @Override @@ -876,7 +879,10 @@ public class DragLayer extends InsettableFrameLayout { getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect); canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE); } - canvas.drawColor((alpha << 24) | SCRIM_COLOR); + // for super light wallpaper it needs to be darken for contrast to workspace + // for dark wallpapers the text is white so darkening works as well + int color = ColorUtils.compositeColors(0x66000000, mWallpaperColorInfo.getMainColor()); + canvas.drawColor(ColorUtils.setAlphaComponent(color, alpha)); canvas.restore(); } diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java b/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java index 5a0e78b12..21d5b2744 100644 --- a/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java +++ b/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java @@ -23,6 +23,7 @@ import android.support.annotation.Nullable; import android.support.v4.graphics.ColorUtils; import android.util.Log; import android.util.Pair; +import android.util.Range; import android.util.SparseIntArray; import com.android.launcher3.R; @@ -51,16 +52,18 @@ public class ColorExtractionAlgorithm { private static final float FIT_WEIGHT_S = 1.0f; private static final float FIT_WEIGHT_L = 10.0f; + // When extracting the main color, only consider colors + // present in at least MIN_COLOR_OCCURRENCE of the image private static final float MIN_COLOR_OCCURRENCE = 0.1f; - private static final float MIN_LUMINOSITY = 0.5f; - public ColorExtractionAlgorithm() { - } + // Temporary variable to avoid allocations + private final float[] mTmpHSL = new float[3]; public @Nullable Pair<Integer, Integer> extractInto(WallpaperColorsCompat wallpaperColors) { if (wallpaperColors == null) { return null; } + SparseIntArray colorsArray = wallpaperColors.getColors(); if (colorsArray.size() == 0) { return null; @@ -71,13 +74,12 @@ public class ColorExtractionAlgorithm { // and replaces the original palette List<Pair<Integer, Integer>> colors = new ArrayList<>(colorsArray.size()); - for (int i = colorsArray.size() - 1; i >= 0; i --) { + for (int i = colorsArray.size() - 1; i >= 0; i--) { colors.add(Pair.create(colorsArray.keyAt(i), colorsArray.valueAt(i))); } // First find the most representative color in the image populationSort(colors); - // Calculate total int total = 0; for (Pair<Integer, Integer> weightedColor : colors) { @@ -96,53 +98,80 @@ public class ColorExtractionAlgorithm { int colorValue = weightedColor.first; ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue), hsl); - if (hsl[2] > MIN_LUMINOSITY) { + + // Stop when we find a color that meets our criteria + if (!isBlacklisted(hsl)) { bestColor = weightedColor; + break; } } - // Fallback to first color + // Fail if not found if (bestColor == null) { - bestColor = colors.get(0); + return null; } int colorValue = bestColor.first; ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue), hsl); - hsl[0] /= 360.0f; // normalize - // TODO, we're finding a tonal palette for a hue, not all components + // The Android HSL definition requires the hue to go from 0 to 360 but + // the Material Tonal Palette defines hues from 0 to 1. + hsl[0] /= 360f; + + // Find the palette that contains the closest color TonalPalette palette = findTonalPalette(hsl[0]); - // Fall back to population sort if we couldn't find a tonal palette if (palette == null) { Log.w(TAG, "Could not find a tonal palette!"); return null; } + // Figure out what's the main color index in the optimal palette int fitIndex = bestFit(palette, hsl[0], hsl[1], hsl[2]); if (fitIndex == -1) { Log.w(TAG, "Could not find best fit!"); return null; } + + // Generate the 10 colors palette by offsetting each one of them float[] h = fit(palette.h, hsl[0], fitIndex, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY); float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f); float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f); + final int textInversionIndex = h.length - 3; - hsl[0] = fract(h[0]) * 360.0f; - hsl[1] = s[0]; - hsl[2] = l[0]; - int mainColor = ColorUtils.HSLToColor(hsl); + // best fit + a 2 colors offset + int primaryIndex = fitIndex; + int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2); + int mainColor = getColorInt(primaryIndex, h, s, l); + int secondaryColor = getColorInt(secondaryIndex, h, s, l); - hsl[0] = fract(h[1]) * 360.0f; - hsl[1] = s[1]; - hsl[2] = l[1]; - int secondaryColor = ColorUtils.HSLToColor(hsl); return new Pair<>(mainColor, secondaryColor); } + private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) { + mTmpHSL[0] = fract(h[fitIndex]) * 360.0f; + mTmpHSL[1] = s[fitIndex]; + mTmpHSL[2] = l[fitIndex]; + return ColorUtils.HSLToColor(mTmpHSL); + } + + /** + * Checks if a given color exists in the blacklist + * @param hsl float array with 3 components (H 0..360, S 0..1 and L 0..1) + * @return true if color should be avoided + */ + private boolean isBlacklisted(float[] hsl) { + for (ColorRange badRange: BLACKLISTED_COLORS) { + if (badRange.containsColor(hsl[0], hsl[1], hsl[2])) { + return true; + } + } + return false; + } + private static void populationSort(@NonNull List<Pair<Integer, Integer>> wallpaperColors) { Collections.sort(wallpaperColors, new Comparator<Pair<Integer, Integer>>() { @Override @@ -160,7 +189,7 @@ public class ColorExtractionAlgorithm { * @param index which index to calculate the delta against * @param min minimum accepted value (clamp) * @param max maximum accepted value (clamp) - * @return + * @return new shifted palette */ private static float[] fit(float[] data, float v, int index, float min, float max) { float[] fitData = new float[data.length]; @@ -272,44 +301,460 @@ public class ColorExtractionAlgorithm { // Data definition of Material Design tonal palettes // When the sort type is set to TONAL, these palettes are used to find - // a best fist. Each palette is defined as 10 HSL colors + // a best fit. Each palette is defined as 22 HSL colors private static final TonalPalette[] TONAL_PALETTES = { - // Orange new TonalPalette( - new float[] { 0.028f, 0.042f, 0.053f, 0.061f, 0.078f, 0.1f, 0.111f, 0.111f, 0.111f, 0.111f }, - new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }, - new float[] { 0.5f, 0.53f, 0.54f, 0.55f, 0.535f, 0.52f, 0.5f, 0.63f, 0.75f, 0.85f } + new float[]{0.991f, 0.9833333333333333f, 0f, 0f, 0f, 0.01134380453752181f, + 0.015625000000000003f, 0.024193548387096798f, 0.027397260273972573f, + 0.017543859649122865f}, + new float[]{1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f, 1f}, + new float[]{0.2f, 0.27450980392156865f, 0.34901960784313724f, + 0.4235294117647059f, 0.5490196078431373f, 0.6254901960784314f, + 0.6862745098039216f, 0.7568627450980392f, 0.8568627450980393f, + 0.9254901960784314f} ), - // Yellow new TonalPalette( - new float[] { 0.111f, 0.111f, 0.125f, 0.133f, 0.139f, 0.147f, 0.156f, 0.156f, 0.156f, 0.156f }, - new float[] { 1f, 0.942f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }, - new float[] { 0.43f, 0.484f, 0.535f, 0.555f, 0.57f, 0.575f, 0.595f, 0.715f, 0.78f, 0.885f } + new float[]{0.6385767790262171f, 0.6301169590643275f, 0.6223958333333334f, + 0.6151079136690647f, 0.6065400843881856f, 0.5986964618249534f, + 0.5910746812386157f, 0.5833333333333334f, 0.5748031496062993f, + 0.5582010582010583f}, + new float[]{1f, 1f, 0.9014084507042253f, 0.8128654970760234f, + 0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f, + 1f, 1f, 1f}, + new float[]{0.17450980392156862f, 0.2235294117647059f, 0.2784313725490196f, + 0.3352941176470588f, 0.388235294117647f, 0.44901960784313727f, + 0.5392156862745098f, 0.6509803921568628f, 0.7509803921568627f, + 0.8764705882352941f} ), - // Green new TonalPalette( - new float[] { 0.325f, 0.336f, 0.353f, 0.353f, 0.356f, 0.356f, 0.356f, 0.356f, 0.356f, 0.356f }, - new float[] { 1f, 1f, 0.852f, 0.754f, 0.639f, 0.667f, 0.379f, 0.542f, 1f, 1f }, - new float[] { 0.06f, 0.1f, 0.151f, 0.194f, 0.25f, 0.312f, 0.486f, 0.651f, 0.825f, 0.885f } + new float[]{0.5669934640522876f, 0.5748031496062993f, + 0.5595238095238095f, 0.5473118279569893f, 0.5393258426966292f, + 0.5315955766192734f, 0.524031007751938f, 0.5154711673699016f, + 0.508080808080808f, 0.5f}, + new float[]{1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f, 1f}, + new float[]{0.2f, 0.24901960784313726f, 0.27450980392156865f, + 0.30392156862745096f, 0.34901960784313724f, 0.4137254901960784f, + 0.47647058823529415f, 0.5352941176470588f, 0.6764705882352942f, 0.8f} ), - // Blue new TonalPalette( - new float[] { 0.631f, 0.603f, 0.592f, 0.586f, 0.572f, 0.544f, 0.519f, 0.519f, 0.519f, 0.519f }, - new float[] { 0.852f, 1f, 0.887f, 0.852f, 0.871f, 0.907f, 0.949f, 0.934f, 0.903f, 0.815f }, - new float[] { 0.34f, 0.38f, 0.482f, 0.497f, 0.536f, 0.571f, 0.608f, 0.696f, 0.794f, 0.892f } + new float[]{0.5082304526748972f, 0.5069444444444444f, 0.5f, 0.5f, + 0.5f, 0.48724954462659376f, 0.4800347222222222f, + 0.4755134281200632f, 0.4724409448818897f, 0.4671052631578947f}, + new float[]{1f, 0.8888888888888887f, 0.9242424242424242f, 1f, 1f, + 0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f}, + new float[]{0.1588235294117647f, 0.21176470588235297f, + 0.25882352941176473f, 0.3f, 0.34901960784313724f, + 0.44117647058823534f, 0.5215686274509804f, 0.5862745098039216f, + 0.7509803921568627f, 0.8509803921568627f} ), - // Purple new TonalPalette( - new float[] { 0.839f, 0.831f, 0.825f, 0.819f, 0.803f, 0.803f, 0.772f, 0.772f, 0.772f, 0.772f }, - new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 0.769f, 0.701f, 0.612f, 0.403f }, - new float[] { 0.125f, 0.15f, 0.2f, 0.245f, 0.31f, 0.36f, 0.567f, 0.666f, 0.743f, 0.833f } + new float[]{0.3333333333333333f, 0.3333333333333333f, + 0.34006734006734f, 0.34006734006734f, 0.34006734006734f, + 0.34259259259259256f, 0.3475783475783476f, 0.34767025089605735f, + 0.3467741935483871f, 0.3703703703703704f}, + new float[]{0.6703296703296703f, 0.728813559322034f, + 0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f, + 0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f}, + new float[]{0.1784313725490196f, 0.23137254901960785f, + 0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f, + 0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f, + 0.8784313725490196f, 0.9294117647058824f} + ), + new TonalPalette( + new float[]{0.162280701754386f, 0.15032679738562088f, + 0.15879265091863518f, 0.16236559139784948f, 0.17443868739205526f, + 0.17824074074074076f, 0.18674698795180725f, + 0.18692449355432778f, 0.1946778711484594f, 0.18604651162790695f}, + new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}, + new float[]{0.14901960784313725f, 0.2f, 0.24901960784313726f, + 0.30392156862745096f, 0.3784313725490196f, 0.4235294117647059f, + 0.48823529411764705f, 0.6450980392156863f, 0.7666666666666666f, + 0.8313725490196078f} + ), + new TonalPalette( + new float[]{0.10619469026548674f, 0.11924686192468618f, + 0.13046448087431692f, 0.14248366013071895f, 0.1506024096385542f, + 0.16220238095238093f, 0.16666666666666666f, + 0.16666666666666666f, 0.162280701754386f, 0.15686274509803924f}, + new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}, + new float[]{0.44313725490196076f, 0.46862745098039216f, + 0.47843137254901963f, 0.5f, 0.5117647058823529f, + 0.5607843137254902f, 0.6509803921568628f, 0.7509803921568627f, + 0.8509803921568627f, 0.9f} + ), + new TonalPalette( + new float[]{0.03561253561253561f, 0.05098039215686275f, + 0.07516339869281045f, 0.09477124183006536f, 0.1150326797385621f, + 0.134640522875817f, 0.14640522875816991f, 0.1582397003745319f, + 0.15773809523809523f, 0.15359477124183002f}, + new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}, + new float[]{0.4588235294117647f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, + 0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f} + ), + new TonalPalette( + new float[]{0.9596491228070175f, 0.9593837535014005f, + 0.9514767932489452f, 0.943859649122807f, 0.9396825396825397f, + 0.9395424836601307f, 0.9393939393939394f, 0.9362745098039216f, + 0.9754098360655739f, 0.9824561403508771f}, + new float[]{0.84070796460177f, 0.8206896551724138f, + 0.7979797979797981f, 0.7661290322580644f, 0.9051724137931036f, + 1f, 1f, 1f, 1f, 1f}, + new float[]{0.22156862745098038f, 0.2843137254901961f, + 0.388235294117647f, 0.48627450980392156f, 0.5450980392156863f, + 0.6f, 0.6764705882352942f, 0.8f, 0.8803921568627451f, + 0.9254901960784314f} + ), + new TonalPalette( + new float[]{0.841025641025641f, 0.8333333333333334f, + 0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f, + 0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f, + 0.7771084337349398f, 0.7747747747747749f}, + new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, + 0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f}, + new float[]{0.12745098039215685f, 0.15490196078431373f, + 0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f, + 0.36470588235294116f, 0.44901960784313727f, + 0.6568627450980392f, 0.7470588235294118f, 0.8450980392156863f} + ), + new TonalPalette( + new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f}, + new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f}, + new float[]{0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f, + 0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f, + 0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f} + ), + new TonalPalette( + new float[]{0.955952380952381f, 0.9681069958847737f, + 0.9760479041916167f, 0.9873563218390804f, 0f, 0f, + 0.009057971014492771f, 0.026748971193415648f, + 0.041666666666666616f, 0.05303030303030304f}, + new float[]{1f, 0.8350515463917526f, 0.6929460580912863f, + 0.6387665198237885f, 0.6914893617021276f, 0.7583892617449666f, + 0.8070175438596495f, 0.9310344827586209f, 1f, 1f}, + new float[]{0.27450980392156865f, 0.3803921568627451f, + 0.4725490196078432f, 0.5549019607843138f, 0.6313725490196078f, + 0.707843137254902f, 0.7764705882352941f, 0.8294117647058823f, + 0.9058823529411765f, 0.9568627450980391f} + ), + new TonalPalette( + new float[]{0.7514619883040936f, 0.7679738562091503f, + 0.7802083333333333f, 0.7844311377245509f, 0.796875f, + 0.8165618448637316f, 0.8487179487179487f, 0.8582375478927203f, + 0.8562091503267975f, 0.8666666666666667f}, + new float[]{1f, 1f, 0.8163265306122449f, 0.6653386454183268f, + 0.7547169811320753f, 0.929824561403509f, 0.9558823529411766f, + 0.9560439560439562f, 1f, 1f}, + new float[]{0.2235294117647059f, 0.3f, 0.38431372549019605f, + 0.492156862745098f, 0.5843137254901961f, 0.6647058823529411f, + 0.7333333333333334f, 0.8215686274509804f, 0.9f, + 0.9411764705882353f} + ), + new TonalPalette( + new float[]{0.6666666666666666f, 0.6666666666666666f, + 0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f, + 0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f, + 0.6666666666666666f, 0.6666666666666666f}, + new float[]{0.24590163934426232f, 0.17880794701986752f, + 0.14606741573033713f, 0.13761467889908252f, 0.14893617021276592f, + 0.16756756756756758f, 0.20312500000000017f, + 0.26086956521739135f, 0.29999999999999966f, 0.5000000000000004f}, + new float[]{0.2392156862745098f, 0.296078431372549f, + 0.34901960784313724f, 0.4274509803921569f, 0.5392156862745098f, + 0.6372549019607843f, 0.7490196078431373f, 0.8196078431372549f, + 0.8823529411764706f, 0.9372549019607843f} + ), + new TonalPalette( + new float[]{0.9678571428571429f, 0.9944812362030905f, 0f, 0f, + 0.0047348484848484815f, 0.00316455696202532f, 0f, + 0.9980392156862745f, 0.9814814814814816f, 0.9722222222222221f}, + new float[]{1f, 0.7023255813953488f, 0.6638655462184874f, + 0.6521739130434782f, 0.7719298245614035f, 0.8315789473684211f, + 0.6867469879518071f, 0.7264957264957265f, 0.8181818181818182f, + 0.8181818181818189f}, + new float[]{0.27450980392156865f, 0.4215686274509804f, + 0.4666666666666667f, 0.503921568627451f, 0.5529411764705883f, + 0.6274509803921569f, 0.6745098039215687f, 0.7705882352941176f, + 0.892156862745098f, 0.9568627450980391f} + ), + new TonalPalette( + new float[]{0.9052287581699346f, 0.9112021857923498f, 0.9270152505446624f, + 0.9343137254901961f, 0.9391534391534391f, 0.9437984496124031f, + 0.943661971830986f, 0.9438943894389439f, 0.9426229508196722f, + 0.9444444444444444f}, + new float[]{1f, 0.8133333333333332f, 0.7927461139896375f, 0.7798165137614679f, + 0.7777777777777779f, 0.8190476190476191f, 0.8255813953488372f, + 0.8211382113821142f, 0.8133333333333336f, 0.8000000000000006f}, + new float[]{0.2f, 0.29411764705882354f, 0.3784313725490196f, + 0.42745098039215684f, 0.4764705882352941f, 0.5882352941176471f, + 0.6627450980392157f, 0.7588235294117647f, 0.8529411764705882f, + 0.9411764705882353f} ), - // Red new TonalPalette( - new float[] { 0.964f, 0.975f, 0.975f, 0.975f, 0.972f, 0.992f, 1.003f, 1.011f, 1.011f, 1.011f }, - new float[] { 0.869f, 0.802f, 0.739f, 0.903f, 1f, 1f, 1f, 1f, 1f, 1f }, - new float[] { 0.241f, 0.316f, 0.46f, 0.586f, 0.655f, 0.7f, 0.75f, 0.8f, 0.84f, 0.88f } + new float[]{0.6884057971014492f, 0.6974789915966387f, 0.7079889807162534f, + 0.7154471544715447f, 0.7217741935483872f, 0.7274143302180687f, + 0.7272727272727273f, 0.7258064516129031f, 0.7252252252252251f, + 0.7333333333333333f}, + new float[]{0.8214285714285715f, 0.6878612716763006f, 0.6080402010050251f, + 0.5774647887323943f, 0.5391304347826086f, 0.46724890829694316f, + 0.4680851063829788f, 0.462686567164179f, 0.45679012345678977f, + 0.4545454545454551f}, + new float[]{0.2196078431372549f, 0.33921568627450976f, 0.39019607843137255f, + 0.4176470588235294f, 0.45098039215686275f, + 0.5509803921568628f, 0.6313725490196078f, 0.7372549019607844f, + 0.8411764705882353f, 0.9352941176470588f} + ), + new TonalPalette( + new float[]{0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f, + 0.6441441441441442f, 0.6432748538011696f, 0.6416666666666667f, + 0.6402439024390243f, 0.6412429378531074f, 0.6435185185185186f, + 0.6428571428571429f}, + new float[]{0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f, + 0.5362318840579711f, 0.5f, 0.4424778761061947f, 0.44086021505376327f, + 0.44360902255639095f, + 0.4499999999999997f, 0.4375000000000006f}, + new float[]{0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f, + 0.40588235294117647f, 0.44705882352941173f, + 0.5568627450980392f, 0.6352941176470588f, 0.7392156862745098f, + 0.8431372549019608f, 0.9372549019607843f} + ), + new TonalPalette( + new float[]{0.46732026143790845f, 0.4718614718614719f, 0.4793650793650794f, + 0.48071625344352614f, 0.4829683698296837f, 0.484375f, + 0.4841269841269842f, 0.48444444444444457f, 0.48518518518518516f, + 0.4907407407407408f}, + new float[]{1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f, + 0.41899441340782106f, 0.4128440366972478f, + 0.4090909090909088f}, + new float[]{0.1f, 0.15098039215686274f, 0.20588235294117646f, + 0.2372549019607843f, 0.26862745098039215f, 0.4f, 0.5078431372549019f, + 0.6490196078431372f, 0.7862745098039216f, 0.9137254901960784f} + ), + new TonalPalette( + new float[]{0.5444444444444444f, 0.5555555555555556f, 0.5555555555555556f, + 0.553763440860215f, 0.5526315789473684f, 0.5555555555555556f, + 0.5555555555555555f, 0.5555555555555556f, 0.5512820512820514f, + 0.5666666666666667f}, + new float[]{0.24590163934426232f, 0.19148936170212766f, 0.1791044776119403f, + 0.18343195266272191f, 0.18446601941747576f, + 0.1538461538461539f, 0.15625000000000003f, 0.15328467153284678f, + 0.15662650602409653f, 0.151515151515151f}, + new float[]{0.1196078431372549f, 0.1843137254901961f, 0.2627450980392157f, + 0.33137254901960783f, 0.403921568627451f, 0.5411764705882354f, + 0.6235294117647059f, 0.7313725490196079f, 0.8372549019607843f, + 0.9352941176470588f} + ), + new TonalPalette( + new float[]{0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f, + 0.03947368421052631f, 0.04166666666666668f, + 0.043650793650793655f, 0.04411764705882352f, 0.04166666666666652f, + 0.04444444444444459f, 0.05555555555555529f}, + new float[]{0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f, + 0.25675675675675674f, 0.2528735632183908f, 0.17500000000000002f, + 0.15315315315315312f, 0.15189873417721522f, + 0.15789473684210534f, 0.15789473684210542f}, + new float[]{0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f, + 0.2901960784313725f, 0.3411764705882353f, 0.47058823529411764f, + 0.5647058823529412f, 0.6901960784313725f, 0.8137254901960784f, + 0.9254901960784314f} + ), + new TonalPalette( + new float[]{0.050884955752212385f, 0.07254901960784313f, 0.0934640522875817f, + 0.10457516339869281f, 0.11699346405228758f, + 0.1255813953488372f, 0.1268939393939394f, 0.12533333333333332f, + 0.12500000000000003f, 0.12777777777777777f}, + new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}, + new float[]{0.44313725490196076f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5784313725490196f, + 0.6549019607843137f, 0.7549019607843137f, 0.8509803921568627f, + 0.9411764705882353f} ) }; + @SuppressWarnings("WeakerAccess") + static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] { + + // Red + new ColorRange( + new Range<>(0f, 20f) /* H */, + new Range<>(0.7f, 1f) /* S */, + new Range<>(0.21f, 0.79f)) /* L */, + new ColorRange( + new Range<>(0f, 20f), + new Range<>(0.3f, 0.7f), + new Range<>(0.355f, 0.653f)), + + // Red Orange + new ColorRange( + new Range<>(20f, 40f), + new Range<>(0.7f, 1f), + new Range<>(0.28f, 0.643f)), + new ColorRange( + new Range<>(20f, 40f), + new Range<>(0.3f, 0.7f), + new Range<>(0.414f, 0.561f)), + new ColorRange( + new Range<>(20f, 40f), + new Range<>(0f, 3f), + new Range<>(0.343f, 0.584f)), + + // Orange + new ColorRange( + new Range<>(40f, 60f), + new Range<>(0.7f, 1f), + new Range<>(0.173f, 0.349f)), + new ColorRange( + new Range<>(40f, 60f), + new Range<>(0.3f, 0.7f), + new Range<>(0.233f, 0.427f)), + new ColorRange( + new Range<>(40f, 60f), + new Range<>(0f, 0.3f), + new Range<>(0.231f, 0.484f)), + + // Yellow 60 + new ColorRange( + new Range<>(60f, 80f), + new Range<>(0.7f, 1f), + new Range<>(0.488f, 0.737f)), + new ColorRange( + new Range<>(60f, 80f), + new Range<>(0.3f, 0.7f), + new Range<>(0.673f, 0.837f)), + + // Yellow Green 80 + new ColorRange( + new Range<>(80f, 100f), + new Range<>(0.7f, 1f), + new Range<>(0.469f, 0.61f)), + + // Yellow green 100 + new ColorRange( + new Range<>(100f, 120f), + new Range<>(0.7f, 1f), + new Range<>(0.388f, 0.612f)), + new ColorRange( + new Range<>(100f, 120f), + new Range<>(0.3f, 0.7f), + new Range<>(0.424f, 0.541f)), + + // Green + new ColorRange( + new Range<>(120f, 140f), + new Range<>(0.7f, 1f), + new Range<>(0.375f, 0.52f)), + new ColorRange( + new Range<>(120f, 140f), + new Range<>(0.3f, 0.7f), + new Range<>(0.435f, 0.524f)), + + // Green Blue 140 + new ColorRange( + new Range<>(140f, 160f), + new Range<>(0.7f, 1f), + new Range<>(0.496f, 0.641f)), + + // Seafoam + new ColorRange( + new Range<>(160f, 180f), + new Range<>(0.7f, 1f), + new Range<>(0.496f, 0.567f)), + + // Cyan + new ColorRange( + new Range<>(180f, 200f), + new Range<>(0.7f, 1f), + new Range<>(0.52f, 0.729f)), + + // Blue + new ColorRange( + new Range<>(220f, 240f), + new Range<>(0.7f, 1f), + new Range<>(0.396f, 0.571f)), + new ColorRange( + new Range<>(220f, 240f), + new Range<>(0.3f, 0.7f), + new Range<>(0.425f, 0.551f)), + + // Blue Purple 240 + new ColorRange( + new Range<>(240f, 260f), + new Range<>(0.7f, 1f), + new Range<>(0.418f, 0.639f)), + new ColorRange( + new Range<>(220f, 240f), + new Range<>(0.3f, 0.7f), + new Range<>(0.441f, 0.576f)), + + // Blue Purple 260 + new ColorRange( + new Range<>(260f, 280f), + new Range<>(0.3f, 1f), // Bigger range + new Range<>(0.461f, 0.553f)), + + // Fuchsia + new ColorRange( + new Range<>(300f, 320f), + new Range<>(0.7f, 1f), + new Range<>(0.484f, 0.588f)), + new ColorRange( + new Range<>(300f, 320f), + new Range<>(0.3f, 0.7f), + new Range<>(0.48f, 0.592f)), + + // Pink + new ColorRange( + new Range<>(320f, 340f), + new Range<>(0.7f, 1f), + new Range<>(0.466f, 0.629f)), + + // Soft red + new ColorRange( + new Range<>(340f, 360f), + new Range<>(0.7f, 1f), + new Range<>(0.437f, 0.596f)) + }; + + /** + * Representation of an HSL color range. + * <ul> + * <li>hsl[0] is Hue [0 .. 360)</li> + * <li>hsl[1] is Saturation [0...1]</li> + * <li>hsl[2] is Lightness [0...1]</li> + * </ul> + */ + static class ColorRange { + private Range<Float> mHue; + private Range<Float> mSaturation; + private Range<Float> mLightness; + + ColorRange(Range<Float> hue, Range<Float> saturation, Range<Float> lightness) { + mHue = hue; + mSaturation = saturation; + mLightness = lightness; + } + + boolean containsColor(float h, float s, float l) { + if (!mHue.contains(h)) { + return false; + } else if (!mSaturation.contains(s)) { + return false; + } else if (!mLightness.contains(l)) { + return false; + } + return true; + } + + float[] getCenter() { + return new float[] { + mHue.getLower() + (mHue.getUpper() - mHue.getLower()) / 2f, + mSaturation.getLower() + (mSaturation.getUpper() - mSaturation.getLower()) / 2f, + mLightness.getLower() + (mLightness.getUpper() - mLightness.getLower()) / 2f + }; + } + + @Override + public String toString() { + return String.format("H: %s, S: %s, L %s", mHue, mSaturation, mLightness); + } + } + } diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java index 06a4dabdd..b9dd3b588 100644 --- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java +++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java @@ -17,9 +17,9 @@ package com.android.launcher3.dynamicui; import android.annotation.TargetApi; -import android.app.IntentService; import android.app.WallpaperManager; -import android.content.Intent; +import android.app.job.JobParameters; +import android.app.job.JobService; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; @@ -27,6 +27,8 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; import android.os.ParcelFileDescriptor; import android.support.v7.graphics.Palette; import android.util.Log; @@ -42,53 +44,84 @@ import java.io.IOException; /** * Extracts colors from the wallpaper, and saves results to {@link LauncherProvider}. */ -public class ColorExtractionService extends IntentService { +public class ColorExtractionService extends JobService { private static final String TAG = "ColorExtractionService"; + private static final boolean DEBUG = false; /** The fraction of the wallpaper to extract colors for use on the hotseat. */ private static final float HOTSEAT_FRACTION = 1f / 4; - public ColorExtractionService() { - super("ColorExtractionService"); - } + private HandlerThread mWorkerThread; + private Handler mWorkerHandler; @Override - protected void onHandleIntent(Intent intent) { - WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); - int wallpaperId = ExtractionUtils.getWallpaperId(wallpaperManager); - - ExtractedColors extractedColors = new ExtractedColors(); - if (wallpaperManager.getWallpaperInfo() != null) { - // We can't extract colors from live wallpapers, so just use the default color always. - extractedColors.updateHotseatPalette(null); + public void onCreate() { + super.onCreate(); + mWorkerThread = new HandlerThread("ColorExtractionService"); + mWorkerThread.start(); + mWorkerHandler = new Handler(mWorkerThread.getLooper()); + } - if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) { - extractedColors.updateWallpaperThemePalette(null); - } - } else { - // We extract colors for the hotseat and status bar separately, - // since they only consider part of the wallpaper. - extractedColors.updateHotseatPalette(getHotseatPalette()); + @Override + public void onDestroy() { + super.onDestroy(); + mWorkerThread.quit(); + } - if (FeatureFlags.LIGHT_STATUS_BAR) { - extractedColors.updateStatusBarPalette(getStatusBarPalette()); - } + @Override + public boolean onStartJob(final JobParameters jobParameters) { + if (DEBUG) Log.d(TAG, "onStartJob"); + mWorkerHandler.post(new Runnable() { + @Override + public void run() { + WallpaperManager wallpaperManager = WallpaperManager.getInstance( + ColorExtractionService.this); + int wallpaperId = ExtractionUtils.getWallpaperId(wallpaperManager); + + ExtractedColors extractedColors = new ExtractedColors(); + if (wallpaperManager.getWallpaperInfo() != null) { + // We can't extract colors from live wallpapers; always use the default color. + extractedColors.updateHotseatPalette(null); + + if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) { + extractedColors.updateWallpaperThemePalette(null); + } + } else { + // We extract colors for the hotseat and status bar separately, + // since they only consider part of the wallpaper. + extractedColors.updateHotseatPalette(getHotseatPalette()); + + if (FeatureFlags.LIGHT_STATUS_BAR) { + extractedColors.updateStatusBarPalette(getStatusBarPalette()); + } + + if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) { + extractedColors.updateWallpaperThemePalette(getWallpaperPalette()); + } + } - if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) { - extractedColors.updateWallpaperThemePalette(getWallpaperPalette()); + // Save the extracted colors and wallpaper id to LauncherProvider. + String colorsString = extractedColors.encodeAsString(); + Bundle extras = new Bundle(); + extras.putInt(LauncherSettings.Settings.EXTRA_WALLPAPER_ID, wallpaperId); + extras.putString(LauncherSettings.Settings.EXTRA_EXTRACTED_COLORS, colorsString); + getContentResolver().call( + LauncherSettings.Settings.CONTENT_URI, + LauncherSettings.Settings.METHOD_SET_EXTRACTED_COLORS_AND_WALLPAPER_ID, + null, extras); + jobFinished(jobParameters, false /* needsReschedule */); + if (DEBUG) Log.d(TAG, "job finished!"); } - } + }); + return true; + } - // Save the extracted colors and wallpaper id to LauncherProvider. - String colorsString = extractedColors.encodeAsString(); - Bundle extras = new Bundle(); - extras.putInt(LauncherSettings.Settings.EXTRA_WALLPAPER_ID, wallpaperId); - extras.putString(LauncherSettings.Settings.EXTRA_EXTRACTED_COLORS, colorsString); - getContentResolver().call( - LauncherSettings.Settings.CONTENT_URI, - LauncherSettings.Settings.METHOD_SET_EXTRACTED_COLORS_AND_WALLPAPER_ID, - null, extras); + @Override + public boolean onStopJob(JobParameters jobParameters) { + if (DEBUG) Log.d(TAG, "onStopJob"); + mWorkerHandler.removeCallbacksAndMessages(null); + return true; } @TargetApi(Build.VERSION_CODES.N) diff --git a/src/com/android/launcher3/dynamicui/ExtractionUtils.java b/src/com/android/launcher3/dynamicui/ExtractionUtils.java index 1cf5d55e0..92cb5dc08 100644 --- a/src/com/android/launcher3/dynamicui/ExtractionUtils.java +++ b/src/com/android/launcher3/dynamicui/ExtractionUtils.java @@ -18,8 +18,10 @@ package com.android.launcher3.dynamicui; import android.annotation.TargetApi; import android.app.WallpaperManager; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; +import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; import android.os.Build; @@ -58,7 +60,11 @@ public class ExtractionUtils { /** Starts the {@link ColorExtractionService} without checking the wallpaper id */ public static void startColorExtractionService(Context context) { - context.startService(new Intent(context, ColorExtractionService.class)); + JobScheduler jobScheduler = (JobScheduler) context.getSystemService( + Context.JOB_SCHEDULER_SERVICE); + jobScheduler.schedule(new JobInfo.Builder(Utilities.COLOR_EXTRACTION_JOB_ID, + new ComponentName(context, ColorExtractionService.class)) + .setMinimumLatency(0).build()); } private static boolean hasWallpaperIdChanged(Context context) { diff --git a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java index ca85b6af1..e23f42f46 100644 --- a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java +++ b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java @@ -33,6 +33,7 @@ public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChange private int mMainColor; private int mSecondaryColor; private boolean mIsDark; + private boolean mSupportsDarkText; private OnThemeChangeListener mOnThemeChangeListener; private WallpaperColorInfo(Context context) { @@ -54,12 +55,17 @@ public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChange return mIsDark; } + public boolean supportsDarkText() { + return mSupportsDarkText; + } + @Override public void onColorsChanged(WallpaperColorsCompat colors, int which) { if (which == FLAG_SYSTEM) { boolean wasDarkTheme = mIsDark; + boolean didSupportDarkText = mSupportsDarkText; update(colors); - notifyChange(wasDarkTheme != mIsDark); + notifyChange(wasDarkTheme != mIsDark || didSupportDarkText != mSupportsDarkText); } } @@ -72,6 +78,7 @@ public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChange mMainColor = FALLBACK_COLOR; mSecondaryColor = FALLBACK_COLOR; } + mSupportsDarkText = wallpaperColors != null ? wallpaperColors.supportsDarkText() : false; float[] hsl = new float[3]; ColorUtils.colorToHSL(mMainColor, hsl); mIsDark = hsl[2] < 0.2f; diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 236bf24a1..b793f491e 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -78,6 +78,7 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.util.Themes; +import com.android.launcher3.graphics.IconPalette; import com.android.launcher3.util.Thunk; import com.android.launcher3.widget.PendingAddShortcutInfo; @@ -933,7 +934,8 @@ public class FolderIcon extends FrameLayout implements FolderListener { // If we are animating to the accepting state, animate the badge out. float badgeScale = Math.max(0, mBadgeScale - mBackground.getScaleProgress()); mTempSpaceForBadgeOffset.set(getWidth() - mTempBounds.right, mTempBounds.top); - mBadgeRenderer.draw(canvas, mBadgeInfo, mTempBounds, + IconPalette badgePalette = IconPalette.getFolderBadgePalette(getResources()); + mBadgeRenderer.draw(canvas, badgePalette, mBadgeInfo, mTempBounds, badgeScale, mTempSpaceForBadgeOffset); } } diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java index 60ca7b236..6e01ed503 100644 --- a/src/com/android/launcher3/graphics/IconPalette.java +++ b/src/com/android/launcher3/graphics/IconPalette.java @@ -18,9 +18,12 @@ package com.android.launcher3.graphics; import android.app.Notification; import android.content.Context; +import android.content.res.Resources; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.graphics.ColorUtils; import android.util.Log; @@ -35,11 +38,12 @@ public class IconPalette { private static final boolean DEBUG = false; private static final String TAG = "IconPalette"; - public static final IconPalette FOLDER_ICON_PALETTE = new IconPalette(Color.parseColor("#BDC1C6")); - private static final float MIN_PRELOAD_COLOR_SATURATION = 0.2f; private static final float MIN_PRELOAD_COLOR_LIGHTNESS = 0.6f; + private static IconPalette sBadgePalette; + private static IconPalette sFolderBadgePalette; + public final int dominantColor; public final int backgroundColor; public final ColorMatrixColorFilter backgroundColorMatrixFilter; @@ -47,15 +51,19 @@ public class IconPalette { public final int textColor; public final int secondaryColor; - private IconPalette(int color) { + private IconPalette(int color, boolean desaturateBackground) { dominantColor = color; - backgroundColor = dominantColor; + backgroundColor = desaturateBackground ? getMutedColor(dominantColor, 0.87f) : dominantColor; ColorMatrix backgroundColorMatrix = new ColorMatrix(); Themes.setColorScaleOnMatrix(backgroundColor, backgroundColorMatrix); backgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix); - // Get slightly more saturated background color. - Themes.setColorScaleOnMatrix(getMutedColor(dominantColor, 0.54f), backgroundColorMatrix); - saturatedBackgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix); + if (!desaturateBackground) { + saturatedBackgroundColorMatrixFilter = backgroundColorMatrixFilter; + } else { + // Get slightly more saturated background color. + Themes.setColorScaleOnMatrix(getMutedColor(dominantColor, 0.54f), backgroundColorMatrix); + saturatedBackgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix); + } textColor = getTextColorForBackground(backgroundColor); secondaryColor = getLowContrastColor(backgroundColor); } @@ -78,8 +86,35 @@ public class IconPalette { return result; } - public static IconPalette fromDominantColor(int dominantColor) { - return new IconPalette(dominantColor); + public static IconPalette fromDominantColor(int dominantColor, boolean desaturateBackground) { + return new IconPalette(dominantColor, desaturateBackground); + } + + /** + * Returns an IconPalette based on the badge_color in colors.xml. + * If that color is Color.TRANSPARENT, then returns null instead. + */ + public static @Nullable IconPalette getBadgePalette(Resources resources) { + int badgeColor = resources.getColor(R.color.badge_color); + if (badgeColor == Color.TRANSPARENT) { + // Colors will be extracted per app icon, so a static palette won't work. + return null; + } + if (sBadgePalette == null) { + sBadgePalette = fromDominantColor(badgeColor, false); + } + return sBadgePalette; + } + + /** + * Returns an IconPalette based on the folder_badge_color in colors.xml. + */ + public static @NonNull IconPalette getFolderBadgePalette(Resources resources) { + if (sFolderBadgePalette == null) { + int badgeColor = resources.getColor(R.color.folder_badge_color); + sFolderBadgePalette = fromDominantColor(badgeColor, false); + } + return sFolderBadgePalette; } /** @@ -134,43 +169,40 @@ public class IconPalette { * This was copied from com.android.internal.util.NotificationColorUtil. */ private static int ensureTextContrast(int color, int bg) { - return findContrastColor(color, bg, true, 4.5); + return findContrastColor(color, bg, 4.5); } /** * Finds a suitable color such that there's enough contrast. * - * @param color the color to start searching from. - * @param other the color to ensure contrast against. Assumed to be lighter than {@param color} - * @param findFg if true, we assume {@param color} is a foreground, otherwise a background. + * @param fg the color to start searching from. + * @param bg the color to ensure contrast against. * @param minRatio the minimum contrast ratio required. * @return a color with the same hue as {@param color}, potentially darkened to meet the * contrast ratio. * * This was copied from com.android.internal.util.NotificationColorUtil. */ - private static int findContrastColor(int color, int other, boolean findFg, double minRatio) { - int fg = findFg ? color : other; - int bg = findFg ? other : color; + private static int findContrastColor(int fg, int bg, double minRatio) { if (ColorUtils.calculateContrast(fg, bg) >= minRatio) { - return color; + return fg; } double[] lab = new double[3]; - ColorUtils.colorToLAB(findFg ? fg : bg, lab); + ColorUtils.colorToLAB(bg, lab); + double bgL = lab[0]; + ColorUtils.colorToLAB(fg, lab); + double fgL = lab[0]; + boolean isBgDark = bgL < 50; - double low = 0, high = lab[0]; + double low = isBgDark ? fgL : 0, high = isBgDark ? 100 : fgL; final double a = lab[1], b = lab[2]; for (int i = 0; i < 15 && high - low > 0.00001; i++) { final double l = (low + high) / 2; - if (findFg) { - fg = ColorUtils.LABToColor(l, a, b); - } else { - bg = ColorUtils.LABToColor(l, a, b); - } + fg = ColorUtils.LABToColor(l, a, b); if (ColorUtils.calculateContrast(fg, bg) > minRatio) { - low = l; + if (isBgDark) high = l; else low = l; } else { - high = l; + if (isBgDark) low = l; else high = l; } } return ColorUtils.LABToColor(low, a, b); diff --git a/src/com/android/launcher3/graphics/IconShapeOverride.java b/src/com/android/launcher3/graphics/IconShapeOverride.java index a0727fb4b..e2d1d50e4 100644 --- a/src/com/android/launcher3/graphics/IconShapeOverride.java +++ b/src/com/android/launcher3/graphics/IconShapeOverride.java @@ -15,13 +15,14 @@ */ package com.android.launcher3.graphics; +import static com.android.launcher3.Utilities.getDevicePrefs; + import android.annotation.TargetApi; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Resources; import android.os.Build; import android.os.SystemClock; @@ -34,7 +35,6 @@ import android.text.TextUtils; import android.util.Log; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherModel; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -101,7 +101,7 @@ public class IconShapeOverride { } catch (Exception e) { Log.e(TAG, "Unable to override icon shape", e); // revert value. - prefs(context).edit().remove(KEY_PREFERENCE).apply(); + getDevicePrefs(context).edit().remove(KEY_PREFERENCE).apply(); } } @@ -116,11 +116,7 @@ public class IconShapeOverride { } private static String getAppliedValue(Context context) { - return prefs(context).getString(KEY_PREFERENCE, ""); - } - - private static SharedPreferences prefs(Context context) { - return context.getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0); + return getDevicePrefs(context).getString(KEY_PREFERENCE, ""); } public static void handlePreferenceUi(ListPreference preference) { @@ -189,7 +185,7 @@ public class IconShapeOverride { @Override public void run() { // Synchronously write the preference. - prefs(mContext).edit().putString(KEY_PREFERENCE, mValue).commit(); + getDevicePrefs(mContext).edit().putString(KEY_PREFERENCE, mValue).commit(); // Clear the icon cache. LauncherAppState.getInstance(mContext).getIconCache().clear(); diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java index 53521f22d..19e570247 100644 --- a/src/com/android/launcher3/graphics/LauncherIcons.java +++ b/src/com/android/launcher3/graphics/LauncherIcons.java @@ -266,9 +266,10 @@ public class LauncherIcons { sOldBounds.set(icon.getBounds()); if (Utilities.isAtLeastO() && icon instanceof AdaptiveIconDrawable) { - int offset = Math.min(left, top); + int offset = Math.max((int)(ShadowGenerator.BLUR_FACTOR * iconBitmapSize), + Math.min(left, top)); int size = Math.max(width, height); - icon.setBounds(offset, offset, offset + size, offset + size); + icon.setBounds(offset, offset, size, size); } else { icon.setBounds(left, top, left+width, top+height); } diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java index 5f4fc6cc7..45c1b6afb 100644 --- a/src/com/android/launcher3/graphics/ShadowDrawable.java +++ b/src/com/android/launcher3/graphics/ShadowDrawable.java @@ -16,6 +16,8 @@ package com.android.launcher3.graphics; +import android.annotation.TargetApi; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -26,7 +28,9 @@ import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.AttributeSet; import com.android.launcher3.R; @@ -40,6 +44,7 @@ import java.io.IOException; /** * A drawable which adds shadow around a child drawable. */ +@TargetApi(Build.VERSION_CODES.O) public class ShadowDrawable extends Drawable { private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); @@ -99,6 +104,24 @@ public class ShadowDrawable extends Drawable { return mState.mIntrinsicWidth; } + @Override + public boolean canApplyTheme() { + return mState.canApplyTheme(); + } + + @Override + public void applyTheme(Resources.Theme t) { + if (mState.canApplyTheme()) { + // Workaround since ColorStateList does not expose applyTheme method + ColorDrawable cd = new ColorDrawable(); + cd.setTintList(mState.mTintColor); + cd.applyTheme(t); + + mState.mLastDrawnBitmap = null; + invalidateSelf(); + } + } + private void regenerateBitmapCache() { Bitmap bitmap = Bitmap.createBitmap(mState.mIntrinsicWidth, mState.mIntrinsicHeight, Bitmap.Config.ARGB_8888); @@ -109,6 +132,9 @@ public class ShadowDrawable extends Drawable { d.setBounds(mState.mShadowSize, mState.mShadowSize, mState.mIntrinsicWidth - mState.mShadowSize, mState.mIntrinsicHeight - mState.mShadowSize); + if (mState.mTintColor != null) { + d.setTint(mState.mTintColor.getDefaultColor()); + } d.draw(canvas); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); @@ -146,6 +172,7 @@ public class ShadowDrawable extends Drawable { R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK); mState.mShadowSize = a.getDimensionPixelSize( R.styleable.ShadowDrawable_android_elevation, 0); + mState.mTintColor = a.getColorStateList(R.styleable.ShadowDrawable_android_tint); mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize; mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize; @@ -165,6 +192,7 @@ public class ShadowDrawable extends Drawable { int mShadowColor; int mShadowSize; + ColorStateList mTintColor; Bitmap mLastDrawnBitmap; ConstantState mChildState; @@ -178,5 +206,10 @@ public class ShadowDrawable extends Drawable { public int getChangingConfigurations() { return mChangingConfigurations; } + + @Override + public boolean canApplyTheme() { + return mTintColor != null; + } } } diff --git a/src/com/android/launcher3/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java index 695015dcb..9ea11a7b2 100644 --- a/src/com/android/launcher3/graphics/ShadowGenerator.java +++ b/src/com/android/launcher3/graphics/ShadowGenerator.java @@ -37,10 +37,10 @@ public class ShadowGenerator { // Percent of actual icon size private static final float HALF_DISTANCE = 0.5f; - private static final float BLUR_FACTOR = 0.5f/48; + public static final float BLUR_FACTOR = 0.5f/48; // Percent of actual icon size - private static final float KEY_SHADOW_DISTANCE = 1f/48; + public static final float KEY_SHADOW_DISTANCE = 1f/48; private static final int KEY_SHADOW_ALPHA = 61; private static final int AMBIENT_SHADOW_ALPHA = 30; diff --git a/src/com/android/launcher3/graphics/TintedDrawableSpan.java b/src/com/android/launcher3/graphics/TintedDrawableSpan.java index f72ce03f4..d7195750d 100644 --- a/src/com/android/launcher3/graphics/TintedDrawableSpan.java +++ b/src/com/android/launcher3/graphics/TintedDrawableSpan.java @@ -34,6 +34,7 @@ public class TintedDrawableSpan extends DynamicDrawableSpan { super(ALIGN_BOTTOM); mDrawable = context.getDrawable(resourceId); mOldTint = 0; + mDrawable.setTint(0); } @Override diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java index be93be4dc..d9c5143f2 100644 --- a/src/com/android/launcher3/model/BgDataModel.java +++ b/src/com/android/launcher3/model/BgDataModel.java @@ -91,11 +91,21 @@ public class BgDataModel { public final Map<ShortcutKey, MutableInt> pinnedShortcutCounts = new HashMap<>(); /** + * True if the launcher has permission to access deep shortcuts. + */ + public boolean hasShortcutHostPermission; + + /** * Maps all launcher activities to the id's of their shortcuts (if they have any). */ public final MultiHashMap<ComponentKey, String> deepShortcutMap = new MultiHashMap<>(); /** + * Entire list of widgets. + */ + public final WidgetsModel widgetsModel = new WidgetsModel(); + + /** * Clears all the data */ public synchronized void clear() { diff --git a/src/com/android/launcher3/model/ExtendedModelTask.java b/src/com/android/launcher3/model/ExtendedModelTask.java index 05419662b..080aaf54b 100644 --- a/src/com/android/launcher3/model/ExtendedModelTask.java +++ b/src/com/android/launcher3/model/ExtendedModelTask.java @@ -59,4 +59,15 @@ public abstract class ExtendedModelTask extends BaseModelUpdateTask { } }); } + + public void bindUpdatedWidgets(BgDataModel dataModel) { + final MultiHashMap<PackageItemInfo, WidgetItem> widgets + = dataModel.widgetsModel.getWidgetsMap(); + scheduleCallbackTask(new CallbackTask() { + @Override + public void execute(Callbacks callbacks) { + callbacks.bindAllWidgets(widgets); + } + }); + } } diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/LoaderResults.java index 61fd356b8..28df64d39 100644 --- a/src/com/android/launcher3/model/LoaderResults.java +++ b/src/com/android/launcher3/model/LoaderResults.java @@ -24,6 +24,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; +import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherModel.Callbacks; import com.android.launcher3.LauncherSettings; import com.android.launcher3.MainThreadExecutor; @@ -58,6 +59,7 @@ public class LoaderResults { private final BgDataModel mBgDataModel; private final AllAppsList mBgAllAppsList; private final int mPageToBindFirst; + private final WeakReference<Callbacks> mCallbacks; public LoaderResults(LauncherAppState app, BgDataModel dataModel, @@ -358,7 +360,6 @@ public class LoaderResults { mUiExecutor.execute(r); } - public void bindAllApps() { // shallow copy @SuppressWarnings("unchecked") @@ -374,4 +375,18 @@ public class LoaderResults { }; mUiExecutor.execute(r); } + + public void bindWidgets() { + final MultiHashMap<PackageItemInfo, WidgetItem> widgets + = mBgDataModel.widgetsModel.getWidgetsMap(); + Runnable r = new Runnable() { + public void run() { + Callbacks callbacks = mCallbacks.get(); + if (callbacks != null) { + callbacks.bindAllWidgets(widgets); + } + } + }; + mUiExecutor.execute(r); + } } diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java new file mode 100644 index 000000000..bcf516eed --- /dev/null +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -0,0 +1,839 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.model; + +import android.appwidget.AppWidgetProviderInfo; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.LauncherActivityInfo; +import android.content.pm.PackageInstaller; +import android.os.Handler; +import android.os.Looper; +import android.os.Process; +import android.os.SystemClock; +import android.os.Trace; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.Log; +import android.util.LongSparseArray; +import android.util.MutableInt; + +import com.android.launcher3.AllAppsList; +import com.android.launcher3.AppInfo; +import com.android.launcher3.FolderInfo; +import com.android.launcher3.IconCache; +import com.android.launcher3.InstallShortcutReceiver; +import com.android.launcher3.ItemInfo; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherAppWidgetInfo; +import com.android.launcher3.LauncherModel; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.ShortcutInfo; +import com.android.launcher3.Utilities; +import com.android.launcher3.compat.AppWidgetManagerCompat; +import com.android.launcher3.compat.LauncherAppsCompat; +import com.android.launcher3.compat.PackageInstallerCompat; +import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.folder.Folder; +import com.android.launcher3.folder.FolderIcon; +import com.android.launcher3.folder.FolderIconPreviewVerifier; +import com.android.launcher3.graphics.LauncherIcons; +import com.android.launcher3.logging.FileLog; +import com.android.launcher3.provider.ImportDataTask; +import com.android.launcher3.shortcuts.DeepShortcutManager; +import com.android.launcher3.shortcuts.ShortcutInfoCompat; +import com.android.launcher3.shortcuts.ShortcutKey; +import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.util.LooperIdleLock; +import com.android.launcher3.util.ManagedProfileHeuristic; +import com.android.launcher3.util.MultiHashMap; +import com.android.launcher3.util.PackageManagerHelper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CancellationException; + +/** + * Runnable for the thread that loads the contents of the launcher: + * - workspace icons + * - widgets + * - all apps icons + * - deep shortcuts within apps + */ +public class LoaderTask implements Runnable { + private static final boolean DEBUG_LOADERS = false; + private static final String TAG = "LoaderTask"; + + private final LauncherAppState mApp; + private final AllAppsList mBgAllAppsList; + private final BgDataModel mBgDataModel; + + private final LoaderResults mResults; + + private final LauncherAppsCompat mLauncherApps; + private final UserManagerCompat mUserManager; + private final DeepShortcutManager mShortcutManager; + private final PackageInstallerCompat mPackageInstaller; + private final AppWidgetManagerCompat mAppWidgetManager; + private final IconCache mIconCache; + + private boolean mStopped; + + public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel, + LoaderResults results) { + mApp = app; + mBgAllAppsList = bgAllAppsList; + mBgDataModel = dataModel; + mResults = results; + + mLauncherApps = LauncherAppsCompat.getInstance(mApp.getContext()); + mUserManager = UserManagerCompat.getInstance(mApp.getContext()); + mShortcutManager = DeepShortcutManager.getInstance(mApp.getContext()); + mPackageInstaller = PackageInstallerCompat.getInstance(mApp.getContext()); + mAppWidgetManager = AppWidgetManagerCompat.getInstance(mApp.getContext()); + mIconCache = mApp.getIconCache(); + } + + private synchronized void waitForIdle() { + // Wait until the either we're stopped or the other threads are done. + // This way we don't start loading all apps until the workspace has settled + // down. + LooperIdleLock idleLock = new LooperIdleLock(this, Looper.getMainLooper()); + // Just in case mFlushingWorkerThread changes but we aren't woken up, + // wait no longer than 1sec at a time + while (!mStopped && idleLock.awaitLocked(1000)); + } + + private synchronized void verifyNotStopped() throws CancellationException { + if (mStopped) { + throw new CancellationException("Loader stopped"); + } + } + + public void run() { + synchronized (this) { + // Skip fast if we are already stopped. + if (mStopped) { + return; + } + } + + try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) { + long now = 0; + if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace"); + loadWorkspace(); + + verifyNotStopped(); + if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace"); + mResults.bindWorkspace(); + + // Take a break + if (DEBUG_LOADERS) { + Log.d(TAG, "step 1 completed, wait for idle"); + now = SystemClock.uptimeMillis(); + } + waitForIdle(); + if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms"); + verifyNotStopped(); + + // second step + if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps"); + loadAllApps(); + + if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Binding all apps"); + verifyNotStopped(); + mResults.bindAllApps(); + + verifyNotStopped(); + if (DEBUG_LOADERS) Log.d(TAG, "step 2.3: Update icon cache"); + updateIconCache(); + + // Take a break + if (DEBUG_LOADERS) { + Log.d(TAG, "step 2 completed, wait for idle"); + now = SystemClock.uptimeMillis(); + } + waitForIdle(); + if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms"); + verifyNotStopped(); + + // third step + if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts"); + loadDeepShortcuts(); + + verifyNotStopped(); + if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts"); + mResults.bindDeepShortcuts(); + + // Take a break + if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle"); + waitForIdle(); + verifyNotStopped(); + + // fourth step + if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets"); + mBgDataModel.widgetsModel.update(mApp, null); + + verifyNotStopped(); + if (DEBUG_LOADERS) Log.d(TAG, "step 4.2: Binding widgets"); + mResults.bindWidgets(); + + transaction.commit(); + } catch (CancellationException e) { + // Loader stopped, ignore + } + } + + public synchronized void stopLocked() { + mStopped = true; + this.notify(); + } + + private void loadWorkspace() { + if (LauncherAppState.PROFILE_STARTUP) { + Trace.beginSection("Loading Workspace"); + } + + final Context context = mApp.getContext(); + final ContentResolver contentResolver = context.getContentResolver(); + final PackageManagerHelper pmHelper = new PackageManagerHelper(context); + final boolean isSafeMode = pmHelper.isSafeMode(); + final boolean isSdCardReady = Utilities.isBootCompleted(); + final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>(); + + boolean clearDb = false; + try { + ImportDataTask.performImportIfPossible(context); + } catch (Exception e) { + // Migration failed. Clear workspace. + clearDb = true; + } + + if (!clearDb && GridSizeMigrationTask.ENABLED && + !GridSizeMigrationTask.migrateGridIfNeeded(context)) { + // Migration failed. Clear workspace. + clearDb = true; + } + + if (clearDb) { + Log.d(TAG, "loadWorkspace: resetting launcher database"); + LauncherSettings.Settings.call(contentResolver, + LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB); + } + + Log.d(TAG, "loadWorkspace: loading default favorites"); + LauncherSettings.Settings.call(contentResolver, + LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES); + + synchronized (mBgDataModel) { + mBgDataModel.clear(); + + final HashMap<String, Integer> installingPkgs = + mPackageInstaller.updateAndGetActiveSessionCache(); + mBgDataModel.workspaceScreens.addAll(LauncherModel.loadWorkspaceScreensDb(context)); + + Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>(); + final LoaderCursor c = new LoaderCursor(contentResolver.query( + LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp); + + HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null; + + try { + final int appWidgetIdIndex = c.getColumnIndexOrThrow( + LauncherSettings.Favorites.APPWIDGET_ID); + final int appWidgetProviderIndex = c.getColumnIndexOrThrow( + LauncherSettings.Favorites.APPWIDGET_PROVIDER); + final int spanXIndex = c.getColumnIndexOrThrow + (LauncherSettings.Favorites.SPANX); + final int spanYIndex = c.getColumnIndexOrThrow( + LauncherSettings.Favorites.SPANY); + final int rankIndex = c.getColumnIndexOrThrow( + LauncherSettings.Favorites.RANK); + final int optionsIndex = c.getColumnIndexOrThrow( + LauncherSettings.Favorites.OPTIONS); + + final LongSparseArray<UserHandle> allUsers = c.allUsers; + final LongSparseArray<Boolean> quietMode = new LongSparseArray<>(); + final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>(); + for (UserHandle user : mUserManager.getUserProfiles()) { + long serialNo = mUserManager.getSerialNumberForUser(user); + allUsers.put(serialNo, user); + quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user)); + + boolean userUnlocked = mUserManager.isUserUnlocked(user); + + // We can only query for shortcuts when the user is unlocked. + if (userUnlocked) { + List<ShortcutInfoCompat> pinnedShortcuts = + mShortcutManager.queryForPinnedShortcuts(null, user); + if (mShortcutManager.wasLastCallSuccess()) { + for (ShortcutInfoCompat shortcut : pinnedShortcuts) { + shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), + shortcut); + } + } else { + // Shortcut manager can fail due to some race condition when the + // lock state changes too frequently. For the purpose of the loading + // shortcuts, consider the user is still locked. + userUnlocked = false; + } + } + unlockedUsers.put(serialNo, userUnlocked); + } + + ShortcutInfo info; + LauncherAppWidgetInfo appWidgetInfo; + Intent intent; + String targetPkg; + + FolderIconPreviewVerifier verifier = + new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile()); + while (!mStopped && c.moveToNext()) { + try { + if (c.user == null) { + // User has been deleted, remove the item. + c.markDeleted("User has been deleted"); + continue; + } + + boolean allowMissingTarget = false; + switch (c.itemType) { + case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: + case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: + case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: + intent = c.parseIntent(); + if (intent == null) { + c.markDeleted("Invalid or null intent"); + continue; + } + + int disabledState = quietMode.get(c.serialNumber) ? + ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0; + ComponentName cn = intent.getComponent(); + targetPkg = cn == null ? intent.getPackage() : cn.getPackageName(); + + if (!Process.myUserHandle().equals(c.user)) { + if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) { + c.markDeleted("Legacy shortcuts are only allowed for default user"); + continue; + } else if (c.restoreFlag != 0) { + // Don't restore items for other profiles. + c.markDeleted("Restore from managed profile not supported"); + continue; + } + } + if (TextUtils.isEmpty(targetPkg) && + c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) { + c.markDeleted("Only legacy shortcuts can have null package"); + continue; + } + + // If there is no target package, its an implicit intent + // (legacy shortcut) which is always valid + boolean validTarget = TextUtils.isEmpty(targetPkg) || + mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user); + + if (cn != null && validTarget) { + // If the apk is present and the shortcut points to a specific + // component. + + // If the component is already present + if (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) { + // no special handling necessary for this item + c.markRestored(); + } else { + if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) { + // We allow auto install apps to have their intent + // updated after an install. + intent = pmHelper.getAppLaunchIntent(targetPkg, c.user); + if (intent != null) { + c.restoreFlag = 0; + c.updater().put( + LauncherSettings.Favorites.INTENT, + intent.toUri(0)).commit(); + cn = intent.getComponent(); + } else { + c.markDeleted("Unable to find a launch target"); + continue; + } + } else { + // The app is installed but the component is no + // longer available. + c.markDeleted("Invalid component removed: " + cn); + continue; + } + } + } + // else if cn == null => can't infer much, leave it + // else if !validPkg => could be restored icon or missing sd-card + + if (!TextUtils.isEmpty(targetPkg) && !validTarget) { + // Points to a valid app (superset of cn != null) but the apk + // is not available. + + if (c.restoreFlag != 0) { + // Package is not yet available but might be + // installed later. + FileLog.d(TAG, "package not yet restored: " + targetPkg); + + if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) { + // Restore has started once. + } else if (installingPkgs.containsKey(targetPkg)) { + // App restore has started. Update the flag + c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED; + c.updater().commit(); + } else { + c.markDeleted("Unrestored app removed: " + targetPkg); + continue; + } + } else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) { + // Package is present but not available. + disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; + // Add the icon on the workspace anyway. + allowMissingTarget = true; + } else if (!isSdCardReady) { + // SdCard is not ready yet. Package might get available, + // once it is ready. + Log.d(TAG, "Missing pkg, will check later: " + targetPkg); + pendingPackages.addToList(c.user, targetPkg); + // Add the icon on the workspace anyway. + allowMissingTarget = true; + } else { + // Do not wait for external media load anymore. + c.markDeleted("Invalid package removed: " + targetPkg); + continue; + } + } + + if (validTarget) { + // The shortcut points to a valid target (either no target + // or something which is ready to be used) + c.markRestored(); + } + + boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() && + !verifier.isItemInPreview(c.getInt(rankIndex)); + + if (c.restoreFlag != 0) { + // Already verified above that user is same as default user + info = c.getRestoredItemInfo(intent); + } else if (c.itemType == + LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { + info = c.getAppShortcutInfo( + intent, allowMissingTarget, useLowResIcon); + } else if (c.itemType == + LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + + ShortcutKey key = ShortcutKey.fromIntent(intent, c.user); + if (unlockedUsers.get(c.serialNumber)) { + ShortcutInfoCompat pinnedShortcut = + shortcutKeyToPinnedShortcuts.get(key); + if (pinnedShortcut == null) { + // The shortcut is no longer valid. + c.markDeleted("Pinned shortcut not found"); + continue; + } + info = new ShortcutInfo(pinnedShortcut, context); + info.iconBitmap = LauncherIcons + .createShortcutIcon(pinnedShortcut, context); + if (pmHelper.isAppSuspended( + pinnedShortcut.getPackage(), info.user)) { + info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; + } + intent = info.intent; + } else { + // Create a shortcut info in disabled mode for now. + info = c.loadSimpleShortcut(); + info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER; + } + } else { // item type == ITEM_TYPE_SHORTCUT + info = c.loadSimpleShortcut(); + + // Shortcuts are only available on the primary profile + if (!TextUtils.isEmpty(targetPkg) + && pmHelper.isAppSuspended(targetPkg, c.user)) { + disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; + } + + // App shortcuts that used to be automatically added to Launcher + // didn't always have the correct intent flags set, so do that + // here + if (intent.getAction() != null && + intent.getCategories() != null && + intent.getAction().equals(Intent.ACTION_MAIN) && + intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { + intent.addFlags( + Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + } + } + + if (info != null) { + c.applyCommonProperties(info); + + info.intent = intent; + info.rank = c.getInt(rankIndex); + info.spanX = 1; + info.spanY = 1; + info.isDisabled |= disabledState; + if (isSafeMode && !Utilities.isSystemApp(context, intent)) { + info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; + } + + if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) { + Integer progress = installingPkgs.get(targetPkg); + if (progress != null) { + info.setInstallProgress(progress); + } else { + info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE; + } + } + + c.checkAndAddItem(info, mBgDataModel); + } else { + throw new RuntimeException("Unexpected null ShortcutInfo"); + } + break; + + case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: + FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id); + c.applyCommonProperties(folderInfo); + + // Do not trim the folder label, as is was set by the user. + folderInfo.title = c.getString(c.titleIndex); + folderInfo.spanX = 1; + folderInfo.spanY = 1; + folderInfo.options = c.getInt(optionsIndex); + + // no special handling required for restored folders + c.markRestored(); + + c.checkAndAddItem(folderInfo, mBgDataModel); + break; + + case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: + case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: + // Read all Launcher-specific widget details + boolean customWidget = c.itemType == + LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; + + int appWidgetId = c.getInt(appWidgetIdIndex); + String savedProvider = c.getString(appWidgetProviderIndex); + + final ComponentName component = + ComponentName.unflattenFromString(savedProvider); + + final boolean isIdValid = !c.hasRestoreFlag( + LauncherAppWidgetInfo.FLAG_ID_NOT_VALID); + final boolean wasProviderReady = !c.hasRestoreFlag( + LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY); + + if (widgetProvidersMap == null) { + widgetProvidersMap = mAppWidgetManager.getAllProvidersMap(); + } + final AppWidgetProviderInfo provider = widgetProvidersMap.get( + new ComponentKey( + ComponentName.unflattenFromString(savedProvider), + c.user)); + + final boolean isProviderReady = isValidProvider(provider); + if (!isSafeMode && !customWidget && + wasProviderReady && !isProviderReady) { + c.markDeleted( + "Deleting widget that isn't installed anymore: " + + provider); + } else { + if (isProviderReady) { + appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, + provider.provider); + + // The provider is available. So the widget is either + // available or not available. We do not need to track + // any future restore updates. + int status = c.restoreFlag & + ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; + if (!wasProviderReady) { + // If provider was not previously ready, update the + // status and UI flag. + + // Id would be valid only if the widget restore broadcast was received. + if (isIdValid) { + status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; + } else { + status &= ~LauncherAppWidgetInfo + .FLAG_PROVIDER_NOT_READY; + } + } + appWidgetInfo.restoreStatus = status; + } else { + Log.v(TAG, "Widget restore pending id=" + c.id + + " appWidgetId=" + appWidgetId + + " status =" + c.restoreFlag); + appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, + component); + appWidgetInfo.restoreStatus = c.restoreFlag; + Integer installProgress = installingPkgs.get(component.getPackageName()); + + if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) { + // Restore has started once. + } else if (installProgress != null) { + // App restore has started. Update the flag + appWidgetInfo.restoreStatus |= + LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; + } else if (!isSafeMode) { + c.markDeleted("Unrestored widget removed: " + component); + continue; + } + + appWidgetInfo.installProgress = + installProgress == null ? 0 : installProgress; + } + if (appWidgetInfo.hasRestoreFlag( + LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) { + appWidgetInfo.bindOptions = c.parseIntent(); + } + + c.applyCommonProperties(appWidgetInfo); + appWidgetInfo.spanX = c.getInt(spanXIndex); + appWidgetInfo.spanY = c.getInt(spanYIndex); + appWidgetInfo.user = c.user; + + if (!c.isOnWorkspaceOrHotseat()) { + c.markDeleted("Widget found where container != " + + "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); + continue; + } + + if (!customWidget) { + String providerName = + appWidgetInfo.providerName.flattenToString(); + if (!providerName.equals(savedProvider) || + (appWidgetInfo.restoreStatus != c.restoreFlag)) { + c.updater() + .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, + providerName) + .put(LauncherSettings.Favorites.RESTORED, + appWidgetInfo.restoreStatus) + .commit(); + } + } + + if (appWidgetInfo.restoreStatus != + LauncherAppWidgetInfo.RESTORE_COMPLETED) { + String pkg = appWidgetInfo.providerName.getPackageName(); + appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg); + appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user; + mIconCache.getTitleAndIconForApp( + appWidgetInfo.pendingItemInfo, false); + } + + c.checkAndAddItem(appWidgetInfo, mBgDataModel); + } + break; + } + } catch (Exception e) { + Log.e(TAG, "Desktop items loading interrupted", e); + } + } + } finally { + Utilities.closeSilently(c); + } + + // Break early if we've stopped loading + if (mStopped) { + mBgDataModel.clear(); + return; + } + + // Remove dead items + if (c.commitDeleted()) { + // Remove any empty folder + ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings + .call(contentResolver, + LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS) + .getSerializable(LauncherSettings.Settings.EXTRA_VALUE); + for (long folderId : deletedFolderIds) { + mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId)); + mBgDataModel.folders.remove(folderId); + mBgDataModel.itemsIdMap.remove(folderId); + } + + // Remove any ghost widgets + LauncherSettings.Settings.call(contentResolver, + LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS); + } + + // Unpin shortcuts that don't exist on the workspace. + HashSet<ShortcutKey> pendingShortcuts = + InstallShortcutReceiver.getPendingShortcuts(context); + for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) { + MutableInt numTimesPinned = mBgDataModel.pinnedShortcutCounts.get(key); + if ((numTimesPinned == null || numTimesPinned.value == 0) + && !pendingShortcuts.contains(key)) { + // Shortcut is pinned but doesn't exist on the workspace; unpin it. + mShortcutManager.unpinShortcut(key); + } + } + + FolderIconPreviewVerifier verifier = + new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile()); + // Sort the folder items and make sure all items in the preview are high resolution. + for (FolderInfo folder : mBgDataModel.folders) { + Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR); + verifier.setFolderInfo(folder); + + int numItemsInPreview = 0; + for (ShortcutInfo info : folder.contents) { + if (info.usingLowResIcon + && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION + && verifier.isItemInPreview(info.rank)) { + mIconCache.getTitleAndIcon(info, false); + numItemsInPreview++; + } + + if (numItemsInPreview >= FolderIcon.NUM_ITEMS_IN_PREVIEW) { + break; + } + } + } + + c.commitRestoredItems(); + if (!isSdCardReady && !pendingPackages.isEmpty()) { + context.registerReceiver( + new SdCardAvailableReceiver(mApp, pendingPackages), + new IntentFilter(Intent.ACTION_BOOT_COMPLETED), + null, + new Handler(LauncherModel.getWorkerLooper())); + } + + // Remove any empty screens + ArrayList<Long> unusedScreens = new ArrayList<>(mBgDataModel.workspaceScreens); + for (ItemInfo item: mBgDataModel.itemsIdMap) { + long screenId = item.screenId; + if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && + unusedScreens.contains(screenId)) { + unusedScreens.remove(screenId); + } + } + + // If there are any empty screens remove them, and update. + if (unusedScreens.size() != 0) { + mBgDataModel.workspaceScreens.removeAll(unusedScreens); + LauncherModel.updateWorkspaceScreenOrder(context, mBgDataModel.workspaceScreens); + } + } + if (LauncherAppState.PROFILE_STARTUP) { + Trace.endSection(); + } + } + + private void updateIconCache() { + // Ignore packages which have a promise icon. + HashSet<String> packagesToIgnore = new HashSet<>(); + synchronized (mBgDataModel) { + for (ItemInfo info : mBgDataModel.itemsIdMap) { + if (info instanceof ShortcutInfo) { + ShortcutInfo si = (ShortcutInfo) info; + if (si.isPromise() && si.getTargetComponent() != null) { + packagesToIgnore.add(si.getTargetComponent().getPackageName()); + } + } else if (info instanceof LauncherAppWidgetInfo) { + LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info; + if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) { + packagesToIgnore.add(lawi.providerName.getPackageName()); + } + } + } + } + mIconCache.updateDbIcons(packagesToIgnore); + } + + private void loadAllApps() { + final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; + + final List<UserHandle> profiles = mUserManager.getUserProfiles(); + + // Clear the list of apps + mBgAllAppsList.clear(); + for (UserHandle user : profiles) { + // Query for the set of apps + final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; + final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user); + if (DEBUG_LOADERS) { + Log.d(TAG, "getActivityList took " + + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user); + Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user); + } + // Fail if we don't have any apps + // TODO: Fix this. Only fail for the current user. + if (apps == null || apps.isEmpty()) { + return; + } + boolean quietMode = mUserManager.isQuietModeEnabled(user); + // Create the ApplicationInfos + for (int i = 0; i < apps.size(); i++) { + LauncherActivityInfo app = apps.get(i); + // This builds the icon bitmaps. + mBgAllAppsList.add(new AppInfo(app, user, quietMode), app); + } + + ManagedProfileHeuristic.onAllAppsLoaded(mApp.getContext(), apps, user); + } + + if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) { + // get all active sessions and add them to the all apps list + for (PackageInstaller.SessionInfo info : + mPackageInstaller.getAllVerifiedSessions()) { + mBgAllAppsList.addPromiseApp(mApp.getContext(), + PackageInstallerCompat.PackageInstallInfo.fromInstallingState(info)); + } + } + + mBgAllAppsList.added = new ArrayList<>(); + if (DEBUG_LOADERS) { + Log.d(TAG, "All apps loaded in in " + + (SystemClock.uptimeMillis() - loadTime) + "ms"); + } + } + + private void loadDeepShortcuts() { + mBgDataModel.deepShortcutMap.clear(); + mBgDataModel.hasShortcutHostPermission = mShortcutManager.hasHostPermission(); + if (mBgDataModel.hasShortcutHostPermission) { + for (UserHandle user : mUserManager.getUserProfiles()) { + if (mUserManager.isUserUnlocked(user)) { + List<ShortcutInfoCompat> shortcuts = + mShortcutManager.queryForAllShortcuts(user); + mBgDataModel.updateDeepShortcutMap(null, user, shortcuts); + } + } + } + } + + public static boolean isValidProvider(AppWidgetProviderInfo provider) { + return (provider != null) && (provider.provider != null) + && (provider.provider.getPackageName() != null); + } +} diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index 8380f0136..46fea218f 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -44,6 +44,7 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.LauncherIcons; import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.ItemInfoMatcher; +import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; @@ -373,11 +374,9 @@ public class PackageUpdatedTask extends ExtendedModelTask { } else if (Utilities.isAtLeastO() && mOp == OP_ADD) { // Load widgets for the new package. for (int i = 0; i < N; i++) { - LauncherModel model = app.getModel(); - model.refreshAndBindWidgetsAndShortcuts( - model.getCallback(), false /* bindFirst */, - new PackageUserKey(packages[i], mUser) /* packageUser */); + dataModel.widgetsModel.update(app, new PackageUserKey(packages[i], mUser)); } + bindUpdatedWidgets(dataModel); } } } diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java index bae5c73c1..3aedae69a 100644 --- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java +++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.Intent; import android.os.UserHandle; +import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.util.MultiHashMap; @@ -43,10 +44,10 @@ public class SdCardAvailableReceiver extends BroadcastReceiver { private final Context mContext; private final MultiHashMap<UserHandle, String> mPackages; - public SdCardAvailableReceiver(LauncherModel model, Context context, + public SdCardAvailableReceiver(LauncherAppState app, MultiHashMap<UserHandle, String> packages) { - mModel = model; - mContext = context; + mModel = app.getModel(); + mContext = app.getContext(); mPackages = packages; } diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java index 827675a83..ed900bf35 100644 --- a/src/com/android/launcher3/model/WidgetsModel.java +++ b/src/com/android/launcher3/model/WidgetsModel.java @@ -38,36 +38,26 @@ public class WidgetsModel { private static final boolean DEBUG = false; /* Map of widgets and shortcuts that are tracked per package. */ - private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList; + private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList = new MultiHashMap<>(); - private final IconCache mIconCache; - private final AppFilter mAppFilter; + private AppFilter mAppFilter; - public WidgetsModel(IconCache iconCache, AppFilter appFilter) { - mIconCache = iconCache; - mAppFilter = appFilter; - mWidgetsList = new MultiHashMap<>(); - } - - public MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() { - return mWidgetsList; - } - - public boolean isEmpty() { - return mWidgetsList.isEmpty(); + public synchronized MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() { + return mWidgetsList.clone(); } /** * @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise * only widgets and shortcuts associated with the package/user are. */ - public ArrayList<WidgetItem> update(Context context, @Nullable PackageUserKey packageUser) { + public void update(LauncherAppState app, @Nullable PackageUserKey packageUser) { Preconditions.assertWorkerThread(); + Context context = app.getContext(); final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>(); try { PackageManager pm = context.getPackageManager(); - InvariantDeviceProfile idp = LauncherAppState.getIDP(context); + InvariantDeviceProfile idp = app.getInvariantDeviceProfile(); // Widgets AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context); @@ -81,7 +71,7 @@ public class WidgetsModel { .getCustomShortcutActivityList(packageUser)) { widgetsAndShortcuts.add(new WidgetItem(info)); } - setWidgetsAndShortcuts(widgetsAndShortcuts, context, packageUser); + setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser); } catch (Exception e) { if (!FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) { // the returned value may be incomplete and will not be refreshed until the next @@ -92,11 +82,12 @@ public class WidgetsModel { throw e; } } - return widgetsAndShortcuts; + + app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser); } - private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts, - Context context, @Nullable PackageUserKey packageUser) { + private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts, + LauncherAppState app, @Nullable PackageUserKey packageUser) { if (DEBUG) { Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size()); } @@ -133,7 +124,7 @@ public class WidgetsModel { } } - InvariantDeviceProfile idp = LauncherAppState.getIDP(context); + InvariantDeviceProfile idp = app.getInvariantDeviceProfile(); UserHandle myUser = Process.myUserHandle(); // add and update. @@ -152,6 +143,9 @@ public class WidgetsModel { } } + if (mAppFilter == null) { + mAppFilter = AppFilter.newInstance(app.getContext()); + } if (!mAppFilter.shouldShowApp(item.componentName)) { if (DEBUG) { Log.d(TAG, String.format("%s is filtered and not added to the widget tray.", @@ -174,8 +168,9 @@ public class WidgetsModel { } // Update each package entry + IconCache iconCache = app.getIconCache(); for (PackageItemInfo p : tmpPackageItemInfos.values()) { - mIconCache.getTitleAndIconForApp(p, true /* userLowResIcon */); + iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */); } } }
\ No newline at end of file diff --git a/src/com/android/launcher3/notification/NotificationFooterLayout.java b/src/com/android/launcher3/notification/NotificationFooterLayout.java index 051c0333d..b83c9b95d 100644 --- a/src/com/android/launcher3/notification/NotificationFooterLayout.java +++ b/src/com/android/launcher3/notification/NotificationFooterLayout.java @@ -205,6 +205,7 @@ public class NotificationFooterLayout extends FrameLayout { collapseFooter.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { + ((ViewGroup) getParent()).findViewById(R.id.divider).setVisibility(GONE); ((ViewGroup) getParent()).removeView(NotificationFooterLayout.this); } }); diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java index 416d546ea..cc81b1121 100644 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ b/src/com/android/launcher3/notification/NotificationItemView.java @@ -34,6 +34,7 @@ import com.android.launcher3.graphics.IconPalette; import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; import com.android.launcher3.popup.PopupItemView; import com.android.launcher3.userevent.nano.LauncherLogProto; +import com.android.launcher3.util.Themes; import java.util.List; @@ -98,7 +99,7 @@ public class NotificationItemView extends PopupItemView implements LogContainerP if (mNotificationHeaderTextColor == Notification.COLOR_DEFAULT) { mNotificationHeaderTextColor = IconPalette.resolveContrastColor(getContext(), palette.dominantColor, - getResources().getColor(R.color.popup_header_background_color)); + Themes.getAttrColor(getContext(), R.attr.popupColorPrimary)); } mHeaderCount.setTextColor(mNotificationHeaderTextColor); } diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java index 0d6da77ee..9b8dd648f 100644 --- a/src/com/android/launcher3/notification/NotificationMainView.java +++ b/src/com/android/launcher3/notification/NotificationMainView.java @@ -87,11 +87,11 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal CharSequence title = mNotificationInfo.title; CharSequence text = mNotificationInfo.text; if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(text)) { - mTitleView.setText(title); - mTextView.setText(text); + mTitleView.setText(title.toString()); + mTextView.setText(text.toString()); } else { mTitleView.setMaxLines(2); - mTitleView.setText(TextUtils.isEmpty(title) ? text : title); + mTitleView.setText(TextUtils.isEmpty(title) ? text.toString() : title.toString()); mTextView.setVisibility(GONE); } iconView.setBackground(mNotificationInfo.getIconForBackground(getContext(), diff --git a/src/com/android/launcher3/pageindicators/CaretDrawable.java b/src/com/android/launcher3/pageindicators/CaretDrawable.java index 416b2f0b5..5ade49728 100644 --- a/src/com/android/launcher3/pageindicators/CaretDrawable.java +++ b/src/com/android/launcher3/pageindicators/CaretDrawable.java @@ -38,6 +38,7 @@ public class CaretDrawable extends Drawable { private Paint mCaretPaint = new Paint(); private Path mPath = new Path(); private final int mCaretSizePx; + private final boolean mUseShadow; public CaretDrawable(Context context) { final Resources res = context.getResources(); @@ -45,7 +46,7 @@ public class CaretDrawable extends Drawable { final int strokeWidth = res.getDimensionPixelSize(R.dimen.all_apps_caret_stroke_width); final int shadowSpread = res.getDimensionPixelSize(R.dimen.all_apps_caret_shadow_spread); - mCaretPaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary)); + mCaretPaint.setColor(Themes.getAttrColor(context, R.attr.workspaceTextColor)); mCaretPaint.setAntiAlias(true); mCaretPaint.setStrokeWidth(strokeWidth); mCaretPaint.setStyle(Paint.Style.STROKE); @@ -60,6 +61,7 @@ public class CaretDrawable extends Drawable { mShadowPaint.setStrokeCap(Paint.Cap.ROUND); mShadowPaint.setStrokeJoin(Paint.Join.ROUND); + mUseShadow = !Themes.getAttrBoolean(context, R.attr.isWorkspaceDarkText); mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size); } @@ -94,8 +96,9 @@ public class CaretDrawable extends Drawable { mPath.moveTo(left, top + caretHeight * (1 - getNormalizedCaretProgress())); mPath.lineTo(left + (width / 2), top + caretHeight * getNormalizedCaretProgress()); mPath.lineTo(left + width, top + caretHeight * (1 - getNormalizedCaretProgress())); - - canvas.drawPath(mPath, mShadowPaint); + if (mUseShadow) { + canvas.drawPath(mPath, mShadowPaint); + } canvas.drawPath(mPath, mCaretPaint); } diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 152886e81..5463ef772 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -35,7 +35,6 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.support.annotation.IntDef; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; @@ -50,7 +49,6 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; -import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; @@ -75,6 +73,7 @@ import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutsItemView; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.Themes; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -278,6 +277,9 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra int footerHeight = notificationFooterHasIcons ? res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0; item.findViewById(R.id.footer).getLayoutParams().height = footerHeight; + if (notificationFooterHasIcons) { + mNotificationItemView.findViewById(R.id.divider).setVisibility(VISIBLE); + } int roundedCorners = ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS; if (shouldUnroundTopCorners) { @@ -286,8 +288,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra if (shouldUnroundBottomCorners) { roundedCorners &= ~ROUNDED_BOTTOM_CORNERS; } - int backgroundColor = ContextCompat.getColor(getContext(), - R.color.notification_color_beneath); + int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorTertiary); mNotificationItemView.setBackgroundWithCorners(backgroundColor, roundedCorners); mNotificationItemView.getMainView().setAccessibilityDelegate(mAccessibilityDelegate); @@ -312,9 +313,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra addView(item); } } - int backgroundColor = ContextCompat.getColor(getContext(), mNotificationItemView == null - ? R.color.popup_background_color - : R.color.popup_header_background_color); + int backgroundColor = Themes.getAttrColor(mLauncher, mNotificationItemView == null + ? R.attr.popupColorPrimary : R.attr.popupColorSecondary); mShortcutsItemView.setBackgroundWithCorners(backgroundColor, shortcutsItemRoundedCorners); } @@ -541,7 +541,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra // since the latter expects the arrow which hasn't been added yet. PopupItemView itemAttachedToArrow = (PopupItemView) (getChildAt(mIsAboveIcon ? getChildCount() - 1 : 0)); - arrowPaint.setColor(ContextCompat.getColor(mLauncher, R.color.popup_background_color)); + arrowPaint.setColor(Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary)); // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable. int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius); arrowPaint.setPathEffect(new CornerPathEffect(radius)); @@ -627,9 +627,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag(); BadgeInfo badgeInfo = mLauncher.getPopupDataProvider().getBadgeInfoForItem(itemInfo); if (mNotificationItemView != null && badgeInfo != null) { - IconPalette palette = mOriginalIcon.getIcon() instanceof FastBitmapDrawable - ? ((FastBitmapDrawable) mOriginalIcon.getIcon()).getIconPalette() - : null; + IconPalette palette = mOriginalIcon.getBadgePalette(); mNotificationItemView.updateHeader(badgeInfo.getNotificationCount(), palette); } } @@ -668,8 +666,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra removeNotification.playSequentially(hideArrow, showArrow); removeNotification.start(); if (mShortcutsItemView != null) { - int backgroundColor = ContextCompat.getColor(getContext(), - R.color.popup_background_color); + int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary); // With notifications gone, all corners of shortcuts item should be rounded. mShortcutsItemView.setBackgroundWithCorners(backgroundColor, ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS); diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java index 3e4cd0192..314f24417 100644 --- a/src/com/android/launcher3/provider/ImportDataTask.java +++ b/src/com/android/launcher3/provider/ImportDataTask.java @@ -16,6 +16,8 @@ package com.android.launcher3.provider; +import static com.android.launcher3.Utilities.getDevicePrefs; + import android.content.ContentProviderOperation; import android.content.ContentValues; import android.content.Context; @@ -36,7 +38,6 @@ import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback; import com.android.launcher3.DefaultLayoutParser; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; -import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherProvider; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; @@ -377,10 +378,6 @@ public class ImportDataTask { return false; } - private static SharedPreferences getDevicePrefs(Context c) { - return c.getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE); - } - private static final int getMyHotseatLayoutId(Context context) { return LauncherAppState.getIDP(context).numHotseatIcons <= 5 ? R.xml.dw_phone_hotseat diff --git a/src/com/android/launcher3/qsb/QsbBlockerView.java b/src/com/android/launcher3/qsb/QsbBlockerView.java deleted file mode 100644 index 5379336de..000000000 --- a/src/com/android/launcher3/qsb/QsbBlockerView.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.qsb; - -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.view.View; - -import com.android.launcher3.Launcher; -import com.android.launcher3.Workspace; -import com.android.launcher3.Workspace.OnStateChangeListener; -import com.android.launcher3.Workspace.State; - -/** - * A simple view used to show the region blocked by QSB during drag and drop. - */ -public class QsbBlockerView extends View implements OnStateChangeListener { - - private static final int VISIBLE_ALPHA = 100; - - private final Paint mBgPaint; - - public QsbBlockerView(Context context, AttributeSet attrs) { - super(context, attrs); - - mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mBgPaint.setColor(Color.WHITE); - mBgPaint.setAlpha(0); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - Workspace w = Launcher.getLauncher(getContext()).getWorkspace(); - w.setOnStateChangeListener(this); - prepareStateChange(w.getState(), null); - } - - @Override - public void prepareStateChange(State toState, AnimatorSet targetAnim) { - int finalAlpha = getAlphaForState(toState); - if (targetAnim == null) { - mBgPaint.setAlpha(finalAlpha); - invalidate(); - } else { - ObjectAnimator anim = ObjectAnimator.ofArgb(mBgPaint, "alpha", finalAlpha); - anim.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - invalidate(); - } - }); - targetAnim.play(anim); - } - } - - private static int getAlphaForState(State state) { - switch (state) { - case SPRING_LOADED: - case OVERVIEW: - case OVERVIEW_HIDDEN: - return VISIBLE_ALPHA; - } - return 0; - } - - @Override - protected void onDraw(Canvas canvas) { - canvas.drawPaint(mBgPaint); - } -} diff --git a/src/com/android/launcher3/shortcuts/ShortcutCache.java b/src/com/android/launcher3/shortcuts/ShortcutCache.java index d4db96d31..5742d1de3 100644 --- a/src/com/android/launcher3/shortcuts/ShortcutCache.java +++ b/src/com/android/launcher3/shortcuts/ShortcutCache.java @@ -19,9 +19,8 @@ package com.android.launcher3.shortcuts; import android.annotation.TargetApi; import android.os.Build; import android.os.UserHandle; +import android.util.ArrayMap; import android.util.LruCache; - -import java.util.HashMap; import java.util.List; /** @@ -31,18 +30,15 @@ import java.util.List; */ @TargetApi(Build.VERSION_CODES.N) public class ShortcutCache { - private static final String TAG = "ShortcutCache"; - private static final boolean LOGD = false; - private static final int CACHE_SIZE = 30; // Max number shortcuts we cache. - private LruCache<ShortcutKey, ShortcutInfoCompat> mCachedShortcuts; + private final LruCache<ShortcutKey, ShortcutInfoCompat> mCachedShortcuts; // We always keep pinned shortcuts in the cache. - private HashMap<ShortcutKey, ShortcutInfoCompat> mPinnedShortcuts; + private final ArrayMap<ShortcutKey, ShortcutInfoCompat> mPinnedShortcuts; public ShortcutCache() { mCachedShortcuts = new LruCache<>(CACHE_SIZE); - mPinnedShortcuts = new HashMap<>(); + mPinnedShortcuts = new ArrayMap<>(); } /** diff --git a/src/com/android/launcher3/util/MultiStateAlphaController.java b/src/com/android/launcher3/util/MultiStateAlphaController.java deleted file mode 100644 index 956fc9eba..000000000 --- a/src/com/android/launcher3/util/MultiStateAlphaController.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.util; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.content.Context; -import android.view.View; -import android.view.accessibility.AccessibilityManager; - -import java.util.Arrays; - -/** - * A utility class which divides the alpha for a view across multiple states. - */ -public class MultiStateAlphaController { - - private final View mTargetView; - private final float[] mAlphas; - private final AccessibilityManager mAm; - private int mZeroAlphaListenerCount = 0; - - public MultiStateAlphaController(View view, int stateCount) { - mTargetView = view; - mAlphas = new float[stateCount]; - Arrays.fill(mAlphas, 1); - - mAm = (AccessibilityManager) view.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); - } - - public void setAlphaAtIndex(float alpha, int index) { - mAlphas[index] = alpha; - updateAlpha(); - } - - private void updateAlpha() { - // Only update the alpha if no zero-alpha animation is running. - if (mZeroAlphaListenerCount > 0) { - return; - } - float finalAlpha = 1; - for (float a : mAlphas) { - finalAlpha = finalAlpha * a; - } - mTargetView.setAlpha(finalAlpha); - mTargetView.setVisibility(finalAlpha > 0 ? View.VISIBLE - : (mAm.isEnabled() ? View.GONE : View.INVISIBLE)); - } - - /** - * Returns an animator which changes the alpha at the index {@param index} - * to {@param finalAlpha}. Alphas at other index are not affected. - */ - public Animator animateAlphaAtIndex(float finalAlpha, final int index) { - final ValueAnimator anim; - - if (Float.compare(finalAlpha, mAlphas[index]) == 0) { - // Return a dummy animator to avoid null checks. - anim = ValueAnimator.ofFloat(0, 0); - } else { - ValueAnimator animator = ValueAnimator.ofFloat(mAlphas[index], finalAlpha); - animator.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - float value = (Float) valueAnimator.getAnimatedValue(); - setAlphaAtIndex(value, index); - } - }); - anim = animator; - } - - if (Float.compare(finalAlpha, 0f) == 0) { - // In case when any channel is animating to 0, and the current alpha is also 0, do not - // update alpha of the target view while the animation is running. - // We special case '0' because if any channel is set to 0, values of other - // channels do not matter. - anim.addListener(new ZeroAlphaAnimatorListener()); - } - return anim; - } - - private class ZeroAlphaAnimatorListener extends AnimatorListenerAdapter { - - private boolean mStartedAtZero = false; - - @Override - public void onAnimationStart(Animator animation) { - mStartedAtZero = Float.compare(mTargetView.getAlpha(), 0f) == 0; - if (mStartedAtZero) { - mZeroAlphaListenerCount++; - mTargetView.setAlpha(0); - } - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mStartedAtZero) { - mZeroAlphaListenerCount--; - updateAlpha(); - } - } - } -} diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java index 9cf45b0c7..89597b9ed 100644 --- a/src/com/android/launcher3/util/Themes.java +++ b/src/com/android/launcher3/util/Themes.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.ColorMatrix; +import android.graphics.drawable.Drawable; /** * Various utility methods associated with theming. @@ -44,6 +45,13 @@ public class Themes { return value; } + public static Drawable getAttrDrawable(Context context, int attr) { + TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); + Drawable value = ta.getDrawable(0); + ta.recycle(); + return value; + } + /** * Returns the alpha corresponding to the theme attribute {@param attr}, in the range [0, 255]. */ |