Merge "Log when users exit Overview mode by tapping on the Workspace." into ub-launcher3-dorval
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 86ae73e..50fb2d7 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -49,7 +49,7 @@
android:fullBackupOnly="true"
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
- android:icon="@mipmap/ic_launcher_home"
+ android:icon="@drawable/ic_launcher_home"
android:label="@string/derived_app_name"
android:largeHeap="@bool/config_largeHeap"
android:restoreAnyVersion="true"
@@ -58,12 +58,21 @@
<!-- Intent received used to install shortcuts from other applications -->
<receiver
android:name="com.android.launcher3.InstallShortcutReceiver"
- android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
+ android:permission="com.android.launcher.permission.INSTALL_SHORTCUT"
+ android:enabled="@bool/enable_install_shortcut_api" >
<intent-filter>
<action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
</intent-filter>
</receiver>
+ <!-- Intent received when a session is committed -->
+ <receiver
+ android:name="com.android.launcher3.SessionCommitReceiver" >
+ <intent-filter>
+ <action android:name="android.content.pm.action.SESSION_COMMITTED" />
+ </intent-filter>
+ </receiver>
+
<!-- Intent received used to initialize a restored widget -->
<receiver android:name="com.android.launcher3.AppWidgetsRestoredReceiver" >
<intent-filter>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 418b3a3..bcb522b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -54,7 +54,7 @@
android:fullBackupOnly="true"
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
- android:icon="@mipmap/ic_launcher_home"
+ android:icon="@drawable/ic_launcher_home"
android:label="@string/derived_app_name"
android:theme="@style/LauncherTheme"
android:largeHeap="@bool/config_largeHeap"
@@ -70,9 +70,10 @@
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
- android:windowSoftInputMode="adjustPan"
+ android:windowSoftInputMode="adjustPan|stateUnchanged"
android:screenOrientation="nosensor"
android:configChanges="keyboard|keyboardHidden|navigation"
+ android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
@@ -134,7 +135,7 @@
android:theme="@android:style/Theme.NoDisplay"
android:label="* HPROF"
android:excludeFromRecents="true"
- android:icon="@mipmap/ic_launcher_home"
+ android:icon="@drawable/ic_launcher_home"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -146,7 +147,7 @@
<activity
android:name="com.android.launcher3.testing.ToggleWeightWatcher"
android:label="Show Mem"
- android:icon="@mipmap/ic_launcher_home">
+ android:icon="@drawable/ic_launcher_home">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/res/drawable-v26/mask_drawable_wrapper.xml b/res/drawable-v26/adaptive_icon_drawable_wrapper.xml
similarity index 90%
rename from res/drawable-v26/mask_drawable_wrapper.xml
rename to res/drawable-v26/adaptive_icon_drawable_wrapper.xml
index 36efd0f..7ad8e2c 100644
--- a/res/drawable-v26/mask_drawable_wrapper.xml
+++ b/res/drawable-v26/adaptive_icon_drawable_wrapper.xml
@@ -14,9 +14,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<maskable-icon xmlns:android="http://schemas.android.com/apk/res/android">
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:color="#FFE0E0E0"/>
<foreground>
<com.android.launcher3.graphics.FixedScaleDrawable />
</foreground>
-</maskable-icon>
+</adaptive-icon>
diff --git a/res/drawable-v26/mask_drawable_wrapper.xml b/res/drawable-v26/ic_launcher_home.xml
similarity index 65%
copy from res/drawable-v26/mask_drawable_wrapper.xml
copy to res/drawable-v26/ic_launcher_home.xml
index 36efd0f..7038775 100644
--- a/res/drawable-v26/mask_drawable_wrapper.xml
+++ b/res/drawable-v26/ic_launcher_home.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 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.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,9 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<maskable-icon xmlns:android="http://schemas.android.com/apk/res/android">
- <background android:color="#FFE0E0E0"/>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@color/icon_background" />
<foreground>
- <com.android.launcher3.graphics.FixedScaleDrawable />
+ <bitmap android:src="@mipmap/ic_launcher_home_foreground"/>
</foreground>
-</maskable-icon>
+</adaptive-icon>
diff --git a/res/drawable/bg_pill_focused.xml b/res/drawable/bg_pill_focused.xml
deleted file mode 100644
index 54075d9..0000000
--- a/res/drawable/bg_pill_focused.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true">
- <shape android:shape="rectangle">
- <stroke android:color="?android:attr/colorControlActivated" android:width="2dp" />
- <corners android:radius="@dimen/bg_pill_radius" />
- </shape>
- </item>
-</selector>
\ No newline at end of file
diff --git a/res/drawable/bg_white_pill.xml b/res/drawable/bg_white_pill.xml
deleted file mode 100644
index f92f739..0000000
--- a/res/drawable/bg_white_pill.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="#FFFFFF" />
- <corners android:radius="@dimen/bg_pill_radius" />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/bg_white_pill_top.xml b/res/drawable/bg_white_pill_top.xml
deleted file mode 100644
index 9988b29..0000000
--- a/res/drawable/bg_white_pill_top.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="#FFFFFF" />
- <corners android:topLeftRadius="@dimen/bg_pill_radius"
- android:topRightRadius="@dimen/bg_pill_radius" />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/bg_white_pill_bottom.xml b/res/drawable/bg_white_round_rect.xml
similarity index 86%
rename from res/drawable/bg_white_pill_bottom.xml
rename to res/drawable/bg_white_round_rect.xml
index a1ea48c..c7f786f 100644
--- a/res/drawable/bg_white_pill_bottom.xml
+++ b/res/drawable/bg_white_round_rect.xml
@@ -17,6 +17,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
- <corners android:bottomLeftRadius="@dimen/bg_pill_radius"
- android:bottomRightRadius="@dimen/bg_pill_radius" />
+ <corners android:radius="@dimen/bg_round_rect_radius" />
</shape>
\ No newline at end of file
diff --git a/res/drawable/horizontal_ellipsis.xml b/res/drawable/horizontal_ellipsis.xml
new file mode 100644
index 0000000..ad08529
--- /dev/null
+++ b/res/drawable/horizontal_ellipsis.xml
@@ -0,0 +1,27 @@
+<?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="@dimen/horizontal_ellipsis_size"
+ android:height="@dimen/horizontal_ellipsis_size"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/textColorSecondary" >
+
+ <path
+ android:pathData="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"
+ android:fillColor="@android:color/white" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/bg_white_pill_bottom.xml b/res/drawable/ic_launcher_home.xml
similarity index 65%
copy from res/drawable/bg_white_pill_bottom.xml
copy to res/drawable/ic_launcher_home.xml
index a1ea48c..a6f2519 100644
--- a/res/drawable/bg_white_pill_bottom.xml
+++ b/res/drawable/ic_launcher_home.xml
@@ -5,7 +5,7 @@
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,10 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="#FFFFFF" />
- <corners android:bottomLeftRadius="@dimen/bg_pill_radius"
- android:bottomRightRadius="@dimen/bg_pill_radius" />
-</shape>
\ No newline at end of file
+<bitmap
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@mipmap/ic_launcher_home" />
diff --git a/res/drawable/ic_star_rating.xml b/res/drawable/ic_star_rating.xml
new file mode 100644
index 0000000..4e34fa3
--- /dev/null
+++ b/res/drawable/ic_star_rating.xml
@@ -0,0 +1,27 @@
+<?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="12dp"
+ android:height="12dp"
+ android:viewportWidth="12"
+ android:viewportHeight="12">
+
+ <path
+ android:fillColor="#FB8C00"
+ android:fillType="evenOdd"
+ android:strokeWidth="1"
+ android:pathData="M 9.76511755 11.9348136 L 8.33665684 7.16088817 L 12.080006 4.41656311 L 7.49967039 4.41856896 L 6.03138903 0 L 4.57932894 4.41856896 L -1.34115008e-16 4.41656311 L 3.72612122 7.16088817 L 2.29967385 11.9348136 L 6.03138903 8.82574452 Z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable-v26/mask_drawable_wrapper.xml b/res/drawable/pending_widget_bg.xml
similarity index 73%
copy from res/drawable-v26/mask_drawable_wrapper.xml
copy to res/drawable/pending_widget_bg.xml
index 36efd0f..cf29f90 100644
--- a/res/drawable-v26/mask_drawable_wrapper.xml
+++ b/res/drawable/pending_widget_bg.xml
@@ -14,9 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<maskable-icon xmlns:android="http://schemas.android.com/apk/res/android">
- <background android:color="#FFE0E0E0"/>
- <foreground>
- <com.android.launcher3.graphics.FixedScaleDrawable />
- </foreground>
-</maskable-icon>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/round_rect_primary"
+ android:inset="@dimen/pending_widget_min_padding" />
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
index 2aae5bc..35bcac3 100644
--- a/res/layout/add_item_confirmation_activity.xml
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -36,12 +36,20 @@
android:background="?android:attr/colorPrimaryDark"
android:layout_height="wrap_content">
- <include
- layout="@layout/widget_cell"
- android:layout_gravity="center_horizontal"
+ <com.android.launcher3.dragndrop.LivePreviewWidgetCell
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:id="@+id/widget_cell" />
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:focusable="true"
+ android:background="?android:attr/colorPrimaryDark"
+ android:gravity="center_horizontal"
+ android:id="@+id/widget_cell"
+ android:layout_gravity="center_horizontal" >
+
+ <include layout="@layout/widget_cell_content" />
+
+ </com.android.launcher3.dragndrop.LivePreviewWidgetCell>
</FrameLayout>
<LinearLayout
diff --git a/res/layout/all_apps_discovery_item.xml b/res/layout/all_apps_discovery_item.xml
new file mode 100644
index 0000000..1a7eaa7
--- /dev/null
+++ b/res/layout/all_apps_discovery_item.xml
@@ -0,0 +1,99 @@
+<?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.
+-->
+<com.android.launcher3.discovery.AppDiscoveryItemView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:background="?android:selectableItemBackground">
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:padding="8dp"
+ android:scaleType="fitCenter"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@id/image">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="?android:textColorSecondary"
+ android:textSize="15sp"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <TextView
+ android:id="@+id/rating"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="?android:textColorSecondary"
+ android:textSize="14sp"
+ android:layout_gravity="center_vertical"/>
+
+ <com.android.launcher3.discovery.RatingView
+ android:id="@+id/rating_view"
+ android:layout_width="80dp"
+ android:layout_height="16dp"
+ android:layout_marginLeft="5dp"
+ android:layout_marginRight="5dp"
+ android:layout_gravity="center_vertical"/>
+
+ <TextView
+ android:id="@+id/review_count"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dp"
+ android:textColor="?android:textColorHint"
+ android:textSize="14sp"
+ android:layout_gravity="center_vertical"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <TextView
+ android:id="@+id/price"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="?android:textColorHint"
+ android:textSize="14sp"
+ android:layout_marginRight="12dp"
+ android:textAllCaps="true"/>
+ </LinearLayout>
+ </LinearLayout>
+
+ <ImageView
+ android:importantForAccessibility="no"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
+ android:paddingRight="@dimen/container_fastscroll_thumb_max_width"
+ android:src="@drawable/all_apps_divider"
+ android:scaleType="fitXY"
+ android:focusable="false" />
+</com.android.launcher3.discovery.AppDiscoveryItemView>
\ No newline at end of file
diff --git a/res/layout/all_apps_discovery_loading_divider.xml b/res/layout/all_apps_discovery_loading_divider.xml
new file mode 100644
index 0000000..c7b5ad2
--- /dev/null
+++ b/res/layout/all_apps_discovery_loading_divider.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:paddingLeft="@dimen/container_fastscroll_thumb_max_width"
+ android:paddingRight="@dimen/container_fastscroll_thumb_max_width">
+
+ <ProgressBar
+ android:id="@+id/loadingProgressBar"
+ style="@android:style/Widget.Material.ProgressBar.Horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="6dp"
+ android:maxHeight="6dp"
+ android:indeterminate="true"
+ android:layout_gravity="center"/>
+
+ <View
+ android:id="@+id/loadedDivider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@drawable/all_apps_divider"
+ android:layout_gravity="center"
+ android:visibility="invisible"/>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml
index 6c1d4da..b2ed709 100644
--- a/res/layout/deep_shortcut.xml
+++ b/res/layout/deep_shortcut.xml
@@ -17,18 +17,16 @@
<com.android.launcher3.shortcuts.DeepShortcutView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="@dimen/bg_pill_width"
- android:layout_height="@dimen/bg_pill_height"
- android:elevation="@dimen/deep_shortcuts_elevation"
- android:background="@drawable/bg_white_pill" >
+ android:layout_width="@dimen/bg_popup_item_width"
+ android:layout_height="@dimen/bg_popup_item_height" >
<com.android.launcher3.shortcuts.DeepShortcutTextView
style="@style/BaseIcon"
android:id="@+id/deep_shortcut"
- android:background="@drawable/bg_pill_focused"
+ android:background="?android:attr/selectableItemBackground"
android:gravity="start|center_vertical"
android:textAlignment="viewStart"
- android:paddingStart="@dimen/bg_pill_height"
+ android:paddingStart="@dimen/bg_popup_item_height"
android:paddingEnd="@dimen/deep_shortcut_padding_end"
android:drawableEnd="@drawable/deep_shortcuts_drag_handle"
android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
@@ -40,10 +38,18 @@
android:elevation="@dimen/deep_shortcuts_elevation" />
<View
- android:id="@+id/popup_item_icon"
+ android:id="@+id/icon"
android:layout_width="@dimen/deep_shortcut_icon_size"
android:layout_height="@dimen/deep_shortcut_icon_size"
android:layout_margin="@dimen/deep_shortcut_padding_start"
android:layout_gravity="start" />
+ <View
+ android:id="@+id/divider"
+ android:layout_width="@dimen/deep_shortcuts_divider_width"
+ android:layout_height="@dimen/popup_item_divider_height"
+ android:layout_gravity="end|bottom"
+ android:visibility="gone"
+ android:background="?android:attr/listDivider" />
+
</com.android.launcher3.shortcuts.DeepShortcutView>
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
index d828c4a..6922ad9 100644
--- a/res/layout/notification.xml
+++ b/res/layout/notification.xml
@@ -17,10 +17,11 @@
<com.android.launcher3.notification.NotificationItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/notification_view"
- android:layout_width="@dimen/bg_pill_width"
+ android:layout_width="@dimen/bg_popup_item_width"
android:layout_height="wrap_content"
android:elevation="@dimen/deep_shortcuts_elevation"
- android:background="@drawable/bg_white_pill">
+ android:background="@drawable/bg_white_round_rect"
+ android:backgroundTint="@color/notification_color_beneath">
<RelativeLayout
android:layout_width="match_parent"
@@ -28,33 +29,49 @@
android:orientation="vertical"
android:clipChildren="false">
- <TextView
+ <com.android.launcher3.notification.NotificationHeaderView
android:id="@+id/header"
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_footer_collapsed_height"
- android:gravity="center_vertical"
- android:textAlignment="center"
- android:text="@string/notifications_header"
- android:elevation="@dimen/notification_elevation"
- android:background="@drawable/bg_white_pill_top" />
-
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_divider_height"
- android:layout_below="@id/header" />
+ android:layout_height="@dimen/notification_header_height"
+ android:orientation="horizontal"
+ android:paddingStart="@dimen/notification_padding"
+ android:background="@color/notification_header_background_color"
+ android:elevation="@dimen/notification_elevation">
+ <TextView
+ android:id="@+id/notification_count"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="start|center_vertical"
+ android:paddingEnd="@dimen/notification_header_padding_after_count"
+ android:textSize="@dimen/notification_main_text_size"
+ android:textColor="?android:attr/textColorPrimary" />
+ <TextView
+ android:id="@+id/notification_text"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="start|center_vertical"
+ android:textSize="@dimen/notification_main_text_size"
+ android:textColor="?android:attr/textColorSecondary" />
+ </com.android.launcher3.notification.NotificationHeaderView>
<include layout="@layout/notification_main"
android:id="@+id/main_view"
android:layout_width="match_parent"
- android:layout_height="@dimen/bg_pill_height"
- android:layout_below="@id/divider" />
+ android:layout_height="@dimen/notification_main_height"
+ android:layout_below="@id/header" />
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/popup_item_divider_height"
+ android:background="@color/divider_color"
+ android:layout_below="@id/main_view"/>
<include layout="@layout/notification_footer"
android:id="@+id/footer"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_footer_height"
- android:layout_below="@id/main_view" />
+ android:layout_below="@id/divider" />
</RelativeLayout>
diff --git a/res/layout/notification_footer.xml b/res/layout/notification_footer.xml
index ceea24a..f1f5724 100644
--- a/res/layout/notification_footer.xml
+++ b/res/layout/notification_footer.xml
@@ -18,25 +18,29 @@
<com.android.launcher3.notification.NotificationFooterLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@drawable/bg_white_pill_bottom"
android:elevation="@dimen/notification_elevation"
- android:clipChildren="false" >
-
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_divider_height"/>
+ android:clipChildren="false"
+ android:layout_gravity="center_vertical"
+ android:background="@color/notification_background_color">
<LinearLayout
android:id="@+id/icon_row"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
+ android:gravity="end|center_vertical"
android:padding="@dimen/notification_footer_icon_row_padding"
android:clipToPadding="false"
android:clipChildren="false"/>
+ <View
+ android:id="@+id/overflow"
+ android:layout_width="@dimen/horizontal_ellipsis_size"
+ android:layout_height="@dimen/horizontal_ellipsis_size"
+ android:background="@drawable/horizontal_ellipsis"
+ android:layout_marginStart="@dimen/horizontal_ellipsis_offset"
+ android:layout_gravity="start|center_vertical" />
+
</com.android.launcher3.notification.NotificationFooterLayout>
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
index 84827f1..9c5847f 100644
--- a/res/layout/notification_main.xml
+++ b/res/layout/notification_main.xml
@@ -19,42 +19,46 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="horizontal"
android:focusable="true"
android:elevation="@dimen/notification_elevation" >
+ <LinearLayout
+ android:id="@+id/text_and_background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:background="@color/notification_background_color"
+ android:paddingStart="@dimen/notification_padding"
+ android:paddingEnd="@dimen/notification_main_text_padding_end">
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="viewStart"
+ android:fontFamily="sans-serif"
+ android:textSize="@dimen/notification_main_text_size"
+ android:textColor="?android:attr/textColorPrimary"
+ android:lines="1"
+ android:ellipsize="end" />
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif"
+ android:textSize="@dimen/notification_main_text_size"
+ android:textColor="?android:attr/textColorSecondary"
+ android:lines="1"
+ android:ellipsize="end" />
+ </LinearLayout>
+
<View
android:id="@+id/popup_item_icon"
android:layout_width="@dimen/notification_icon_size"
android:layout_height="@dimen/notification_icon_size"
- android:layout_marginStart="@dimen/notification_icon_margin_start"
- android:layout_gravity="center_vertical" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginStart="@dimen/notification_text_margin_start"
- android:gravity="center_vertical">
- <TextView
- android:id="@+id/title"
- android:textAlignment="viewStart"
- android:fontFamily="sans-serif"
- android:textSize="14sp"
- android:textColor="?android:attr/textColorSecondary"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- android:id="@+id/text"
- android:paddingEnd="4dp"
- android:textSize="12sp"
- android:textAlignment="viewStart"
- android:fontFamily="sans-serif"
- android:textColor="?android:attr/textColorTertiary"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
+ android:layout_marginEnd="@dimen/notification_padding"
+ android:layout_gravity="center_vertical|end" />
</com.android.launcher3.notification.NotificationMainView>
diff --git a/res/layout/shortcuts_item.xml b/res/layout/shortcuts_item.xml
new file mode 100644
index 0000000..8b20bcb
--- /dev/null
+++ b/res/layout/shortcuts_item.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<com.android.launcher3.shortcuts.ShortcutsItemView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/shortcuts_view"
+ android:layout_width="@dimen/bg_popup_item_width"
+ android:layout_height="wrap_content"
+ android:elevation="@dimen/deep_shortcuts_elevation"
+ android:background="@drawable/bg_white_round_rect">
+
+ <LinearLayout
+ android:id="@+id/deep_shortcuts"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ </LinearLayout>
+
+</com.android.launcher3.shortcuts.ShortcutsItemView>
diff --git a/res/layout/widget_cell.xml b/res/layout/widget_cell.xml
index b9b098c..148a99b 100644
--- a/res/layout/widget_cell.xml
+++ b/res/layout/widget_cell.xml
@@ -23,49 +23,6 @@
android:background="?android:attr/colorPrimaryDark"
android:gravity="center_horizontal">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/widget_preview_label_vertical_padding"
- android:paddingBottom="@dimen/widget_preview_label_vertical_padding"
- android:paddingLeft="@dimen/widget_preview_label_horizontal_padding"
- android:paddingRight="@dimen/widget_preview_label_horizontal_padding"
- android:orientation="horizontal">
+ <include layout="@layout/widget_cell_content" />
- <!-- The name of the widget. -->
- <TextView
- android:id="@+id/widget_name"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:ellipsize="end"
- android:fadingEdge="horizontal"
- android:fontFamily="sans-serif-condensed"
- android:gravity="start"
- android:singleLine="true"
- android:maxLines="1"
- android:textColor="?android:attr/textColorSecondary"
- android:textSize="14sp" />
-
- <!-- The original dimensions of the widget (can't be the same text as above due to different
- style. -->
- <TextView
- android:id="@+id/widget_dims"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="5dp"
- android:layout_marginLeft="5dp"
- android:textColor="?android:attr/textColorSecondary"
- android:textSize="14sp"
- android:fontFamily="sans-serif-condensed"
- android:alpha="0.8" />
- </LinearLayout>
-
- <!-- The image of the widget. This view does not support padding. Any placement adjustment
- should be done using margins. -->
- <com.android.launcher3.widget.WidgetImageView
- android:id="@+id/widget_preview"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
</com.android.launcher3.widget.WidgetCell>
\ No newline at end of file
diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml
new file mode 100644
index 0000000..c77b0b9
--- /dev/null
+++ b/res/layout/widget_cell_content.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/widget_preview_label_vertical_padding"
+ android:paddingBottom="@dimen/widget_preview_label_vertical_padding"
+ android:paddingLeft="@dimen/widget_preview_label_horizontal_padding"
+ android:paddingRight="@dimen/widget_preview_label_horizontal_padding"
+ android:orientation="horizontal">
+
+ <!-- The name of the widget. -->
+ <TextView
+ android:id="@+id/widget_name"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:ellipsize="end"
+ android:fadingEdge="horizontal"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="start"
+ android:singleLine="true"
+ android:maxLines="1"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textSize="14sp" />
+
+ <!-- The original dimensions of the widget (can't be the same text as above due to different
+ style. -->
+ <TextView
+ android:id="@+id/widget_dims"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="5dp"
+ android:layout_marginLeft="5dp"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textSize="14sp"
+ android:fontFamily="sans-serif-condensed"
+ android:alpha="0.8" />
+ </LinearLayout>
+
+ <!-- The image of the widget. This view does not support padding. Any placement adjustment
+ should be done using margins. -->
+ <com.android.launcher3.widget.WidgetImageView
+ android:id="@+id/widget_preview"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+</merge>
\ No newline at end of file
diff --git a/res/layout/widgets_list_row_view.xml b/res/layout/widgets_list_row_view.xml
index 5c2e230..4067503 100644
--- a/res/layout/widgets_list_row_view.xml
+++ b/res/layout/widgets_list_row_view.xml
@@ -34,7 +34,6 @@
android:ellipsize="end"
android:focusable="true"
android:gravity="start|center_vertical"
- android:importantForAccessibility="no"
android:paddingBottom="@dimen/widget_section_vertical_padding"
android:paddingLeft="@dimen/widget_section_horizontal_padding"
android:paddingRight="@dimen/widget_section_horizontal_padding"
diff --git a/res/mipmap-hdpi/ic_launcher_home_foreground.png b/res/mipmap-hdpi/ic_launcher_home_foreground.png
new file mode 100644
index 0000000..d068d92
--- /dev/null
+++ b/res/mipmap-hdpi/ic_launcher_home_foreground.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_home_foreground.png b/res/mipmap-mdpi/ic_launcher_home_foreground.png
new file mode 100644
index 0000000..0ed9f4d
--- /dev/null
+++ b/res/mipmap-mdpi/ic_launcher_home_foreground.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_home_foreground.png b/res/mipmap-xhdpi/ic_launcher_home_foreground.png
new file mode 100644
index 0000000..7a9daf5
--- /dev/null
+++ b/res/mipmap-xhdpi/ic_launcher_home_foreground.png
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_home_foreground.png b/res/mipmap-xxhdpi/ic_launcher_home_foreground.png
new file mode 100644
index 0000000..03b493e
--- /dev/null
+++ b/res/mipmap-xxhdpi/ic_launcher_home_foreground.png
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 5fe2f1d..7d4a697 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dubbeltik en hou om \'n legstuk op te tel of gebruik gepasmaakte handelinge."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Raak en hou om op tuisskerm te plaas"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Plaas outomaties"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Deursoek programme"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Laai tans programme …"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Geen programme gevind wat met \"<xliff:g id="QUERY">%1$s</xliff:g>\" ooreenstem nie"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer foon gedraai word"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Huidige vertooninstelling laat nie rotasie toe nie"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Voeg ikoon by tuisskerm"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Vir nuwe programme"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Verwyder"</string>
<string name="abandoned_search" msgid="891119232568284442">"Soek"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 92f83ed..9f07b44 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"አንድ ንዑስ ፕሮግራም ለመምረጥ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ስፋት በ%2$d ከፍታ"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"በመነሻ ማያ ገጽ ላይ ለማስቀመጥ ነካ ያድርጉ እና ይያዙ"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"በራስ-ሰር ያስቀምጡ"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"መተግበሪያዎችን ይፈልጉ"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"መተግበሪያዎችን በመጫን ላይ..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ስልኩ ሲዞር"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"የአሁኑ የማሳያ ቅንብር ማሽከርከርን አይፈቅድም"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"አዶ ወደ የመነሻ ማያ ገጽ አክል"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ለአዲስ መተግበሪያዎች"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"የማይታወቅ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"አስወግድ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ፈልግ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 3862774..fcadbe1 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"انقر نقرًا مزدوجًا مع الاستمرار لاختيار أداة أو استخدم الإجراءات المخصصة."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"العرض %1$d الطول %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"المس الرمز مع الاستمرار لوضعه على الشاشة الرئيسية"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"إضافة الرمز إلى الشاشة الرئيسية تلقائيًا"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"البحث في التطبيقات"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"جارٍ تحميل التطبيقات…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"لم يتم العثور على أية تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"لا يسمح إعداد العرض الحالي بالتدوير"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"إضافة رمز إلى الشاشة الرئيسية"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"للتطبيقات الجديدة"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"غير معروفة"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"إزالة"</string>
<string name="abandoned_search" msgid="891119232568284442">"بحث"</string>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index d38e4ed..e37cdf9 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Vidceti götürmək üçün & iki dəfə toxunub saxlayın və ya fərdi fəaliyyətləri istifadə edin."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d hündürlük %1$d enində"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Əsas ekranda yerləşdirmək üçün toxunub saxlayın"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Avtomatik yerləşdirin"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tətbiq Axtarın"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Tətbiqlər endirilir..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" sorğusuna uyğun Tətbiqlər tapılmadı"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon çevrilən zaman"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cari Ekran ayarı fırlatmağa icazə vermir"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Əsas ekrana ikona əlavə edin"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni tətbiqlər üçün"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Naməlum"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Yığışdır"</string>
<string name="abandoned_search" msgid="891119232568284442">"Axtarış"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 4b9bba6..0f1b24a 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Докоснете двукратно и задръжте за избор на приспособление или използвайте персонализирани действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d и височина %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Докоснете и задръжте, за да поставите на началния екран"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Автоматично поставяне"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Търсене в приложенията"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Приложенията се зареждат…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"При завъртане на телефона"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Текущата настройка на екрана не разрешава завъртане"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавяне на икона към началния екран"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови приложения"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Няма информация"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Премахване"</string>
<string name="abandoned_search" msgid="891119232568284442">"Търсене"</string>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 0d639a6..eaad010 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"কোনো উইজেট বেছে নিতে দুবার-আলতো চেপে ধরে থাকুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন৷"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"হোম স্ক্রিনে রাখতে টাচ করে ধরে থাকুন"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"স্বয়ংক্রিয়ভাবে রাখুন"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"অ্যাপ্লিকেশানগুলি অনুসন্ধান করুন"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"অ্যাপ্লিকেশানগুলি লোড হচ্ছে..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"যখন ফোনটি ঘোরানো হয়"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"বর্তমান প্রদর্শনের সেটিংস ঘোরানোর মঞ্জুরি দেয় না"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"হোম স্ক্রিনে আইকন যোগ করুন"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"অজানা"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"সরান"</string>
<string name="abandoned_search" msgid="891119232568284442">"অনুসন্ধান"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 36d18bf..dfbfe8c 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Fes doble toc i mantén premut per seleccionar un widget o per utilitzar les accions personalitzades."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Toca i mantén premut l\'element per col·locar-lo a la pantalla d\'inici"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Col·loca automàticament"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cerca a les aplicacions"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"S\'estan carregant les aplicacions..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"No s\'ha trobat cap aplicació que coincideixi amb <xliff:g id="QUERY">%1$s</xliff:g>"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"En girar el telèfon"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuració actual de la pantalla no permet la rotació"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Afegeix la icona a la pantalla d\'inici"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per a les aplicacions noves"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconegut"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Suprimeix"</string>
<string name="abandoned_search" msgid="891119232568284442">"Cerca"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index d34c22b..6f19c0e 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvojitým klepnutím a podržením vyberte widget, případně použijte vlastní akce."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Chcete-li položku umístit na plochu, klepněte na ni a podržte ji"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Umístit automaticky"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Hledat aplikace"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Načítání aplikací…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Při otočení telefonu"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuální nastavení displeje neumožňuje otáčení"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Přidat ikonu na plochu"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pro nové aplikace"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Neznámé"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Odstranit"</string>
<string name="abandoned_search" msgid="891119232568284442">"Hledat"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 009750c..2186fb4 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryk to gange, og hold fingeren nede for at vælge en widget eller bruge tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Tryk, og hold fingeren nede for at placere på startskærmen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Placer automatisk"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Søg i Apps"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Indlæser apps…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Den aktuelle indstilling for visning tillader ikke rotation"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Føj ikon til startskærmen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ukendt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Fjern"</string>
<string name="abandoned_search" msgid="891119232568284442">"Søg"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index e28517b..f97f028 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Zum Hinzufügen auf Widget doppeltippen und gedrückt halten oder benutzerdefinierte Aktionen verwenden."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Zum Hinzufügen zum Startbildschirm gedrückt halten"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Automatisch hinzufügen"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"In Apps suchen"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Apps werden geladen..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Drehung des Startbildschirms zulassen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Bei Drehung des Smartphones"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Die aktuelle \"Display\"-Einstellung verhindert eine Drehung der Anzeige"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Symbol zu Startbildschirm hinzufügen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Für neue Apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unbekannt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Entfernen"</string>
<string name="abandoned_search" msgid="891119232568284442">"Suchen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 00be6b3..e045d2b 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Πατήστε δύο φορές παρατεταμένα για επιλογή γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Πλάτος %1$d επί ύψος %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Αγγίξτε παρατεταμένα για να το τοποθετήσετε στην αρχική οθόνη"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Αυτόματη τοποθέτηση"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Αναζήτηση εφαρμογών"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Φόρτωση εφαρμογών…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Δεν βρέθηκαν εφαρμογές για το ερώτημα \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Όταν το τηλέφωνο περιστρέφεται"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Η τρέχουσα ρύθμιση οθόνης δεν επιτρέπει την περιστροφή"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Προσθήκη εικονιδίου στην Αρχική οθόνη"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Για νέες εφαρμογές"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Άγνωστο"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Κατάργηση"</string>
<string name="abandoned_search" msgid="891119232568284442">"Αναζήτηση"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 15e3b47..d6c837b 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap & hold to pick up a widget or use customised actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Touch & hold to place on home screen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Place automatically"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
<string name="abandoned_search" msgid="891119232568284442">"Search"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 15e3b47..d6c837b 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap & hold to pick up a widget or use customised actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Touch & hold to place on home screen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Place automatically"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
<string name="abandoned_search" msgid="891119232568284442">"Search"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 15e3b47..d6c837b 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap & hold to pick up a widget or use customised actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Touch & hold to place on home screen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Place automatically"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Current display setting doesn\'t permit rotation"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
<string name="abandoned_search" msgid="891119232568284442">"Search"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 791cf98..1a7b561 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Presiona dos veces y mantén presionado para elegir un widget o usa una acción personalizada."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Mantén presionado para ubicarlo en la pantalla principal"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Ubicar de manera automática"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Buscar aplicaciones"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicaciones…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"No hay aplicaciones que coincidan con <xliff:g id="QUERY">%1$s</xliff:g>."</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir la rotación de la pantalla principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuración actual no permite la rotación de la pantalla"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Agregar ícono a la pantalla principal"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para nuevas apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index da229d6..9b80c56 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toca dos veces y mantén pulsado el widget que quieras seleccionar o utiliza acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Mantén pulsado el elemento para añadirlo a la pantalla de inicio"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Añadir automáticamente"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Busca aplicaciones"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicaciones…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"La configuración de pantalla actual no permite girar la pantalla"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Añadir icono a la pantalla de inicio"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para nuevas aplicaciones"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Quitar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 5b376cc..07834dc 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Topeltpuudutage ja hoidke vidina valimiseks või kohandatud toimingute kasutamiseks."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Puudutage pikalt avaekraanile paigutamiseks"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Paiguta automaatselt"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Otsige rakendustest"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Rakenduste laadimine ..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Luba avaekraani pööramine"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kui telefoni pööratakse"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Praegune kuvaseade ei luba pööramist"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisa ikoon avaekraanile"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uute rakenduste puhul"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Teadmata"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eemalda"</string>
<string name="abandoned_search" msgid="891119232568284442">"Otsing"</string>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index f6062db..17ce6d0 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Sakatu birritan eta eduki sakatuta widgeta aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d zabal eta %2$d luze"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Eduki sakatuta jarri nahi duzun tokia hasierako pantailan"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Jarri automatikoki"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Bilatu aplikazioetan"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Aplikazioak kargatzen…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketarekin bat datorren aplikaziorik"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Baimendu hasierako pantaila biratzea"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzen denean"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Uneko pantaila-ezarpenak ez du onartzen ikuspegia biratzea"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Gehitu ikonoa hasierako pantailan"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Aplikazio berrietan"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ezezaguna"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Kendu"</string>
<string name="abandoned_search" msgid="891119232568284442">"Bilatu"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 5a29aae..9bbecca 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"برای انتخاب یک ابزارک، دو ضربه سریع بزنید و نگهدارید یا از اقدامات سفارشی استفاده کنید."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d عرض در %2$d طول"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"برای قرار دادن در صفحه اصلی لمس کنید و نگهدارید"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"افزودن خودکار"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"جستجوی برنامهها"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"در حال بارگیری برنامهها..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"هیچ برنامهای مطابق با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"امکان دادن به چرخش صفحه اصلی"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"وقتی تلفن چرخانده میشود"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"تنظیم نمایشگر کنونی اجازه چرخش نمیدهد"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"افزودن نماد به صفحه اصلی"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"برای برنامههای جدید"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"نامشخص"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"حذف"</string>
<string name="abandoned_search" msgid="891119232568284442">"جستجو"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index f0a1211..6595f86 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Valitse widget tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla kohdetta pitkään."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Sijoita aloitusnäytölle koskettamalla pitkään."</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Sijoita automaattisesti"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sovellushaku"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Ladataan sovelluksia…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"”<xliff:g id="QUERY">%1$s</xliff:g>” ei palauttanut sovelluksia."</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kun puhelinta kierretään"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Nykyiset näyttöasetukset eivät salli näytön kiertämistä."</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisää kuvake aloitusruutuun"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uusille sovelluksille"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Tuntematon"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Poista"</string>
<string name="abandoned_search" msgid="891119232568284442">"Haku"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 6509f29..5d9f041 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Touchez 2x un widget et maintenez doigt dessus pour l’ajouter ou utiliser des actions personnalisées"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Maintenez le doigt sur l\'élément pour le placer sur l\'écran d\'accueil"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Placer automatiquement"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Rechercher des applications"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Chargement des applications en cours..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Le mode d\'affichage actuel ne permet pas le pivotement"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Supprimer"</string>
<string name="abandoned_search" msgid="891119232568284442">"Rechercher"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index d3a15b1..2090262 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Appuyez 2 fois et maintenez la pression pour sélectionner widget ou utilisez actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Appuyez de manière prolongée pour placer l\'élément sur l\'écran d\'accueil"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Placer automatiquement"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Rechercher dans les applications"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Chargement des applications en cours…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\"."</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Le paramètre d\'affichage actuel n\'autorise pas la rotation."</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Supprimer"</string>
<string name="abandoned_search" msgid="891119232568284442">"Rechercher"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index b3e8a69..fbadfe0 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toca dúas veces e mantén premido para seleccionar un widget ou utiliza accións personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largo por %2$d de alto"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Mantén premido o elemento para colocalo na pantalla de inicio"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Colocar automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Aplicacións de busca"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicacións..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ao xirar o teléfono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A configuración de visualización actual non permite xirar a pantalla"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engadir icona á pantalla de inicio"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicacións"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Descoñecido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index d61df90..557896f 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"વિજેટ ચૂંટવા અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટેપ કરો અને પકડી રાખો."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d પહોળાઈ X %2$d ઊંચાઈ"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"હોમ સ્ક્રીન પર મૂકવા માટે ટચ કરો અને પકડો"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"આપમેળે મૂકો"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"શોધ ઍપ્લિકેશનો"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"વર્તમાન પ્રદર્શન સેટિંગ ફેરવવાની પરવાનગી આપતી નથી"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"હોમ સ્ક્રીન પર આઇકન ઉમેરો"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"અજાણ્યો"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"દૂર કરો"</string>
<string name="abandoned_search" msgid="891119232568284442">"શોધો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 900ebb0..ad33aca 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"कोई विजेट चुनने के लिए डबल टैप करके रखें या कस्टम कार्रवाइयां चुनें."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौड़ाई गुणा %2$d ऊंचाई"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"होम स्क्रीन पर रखने के लिए स्पर्श करके रखें"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"अपने आप रखें"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ऐप्स खोजें"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ऐप्स लोड हो रहे हैं..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलान करने वाला कोई ऐप नहीं मिला"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फ़ोन घुुमाए जाने पर"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग घुमाने की अनुमति नहीं देती"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीन में आइकन जोड़ें"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नए ऐप्लिकेशन के लिए"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"निकालें"</string>
<string name="abandoned_search" msgid="891119232568284442">"खोजें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index a74de33..0e01e72 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dodirnite dvaput i držite kako biste podigli widget ili pokušajte prilagođenim radnjama."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Dodirnite i zadržite stavku da biste je postavili na početni zaslon"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Postavi automatski"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretraži aplikacije"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Učitavanje aplikacija…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Dopusti zakretanje početnog zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zakrene"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutačna postavka zaslona ne dopušta zakretanje"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni zaslon"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
<string name="abandoned_search" msgid="891119232568284442">"Traži"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 6334433..bcbe52f 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Modul mozgatásához koppintson rá duplán és tartsa lenyomva, vagy használjon egyéni műveleteket."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Tartsa lenyomva, hogy elhelyezhesse a kezdőképernyőn"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Automatikus elhelyezés"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Alkalmazások keresése"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Alkalmazások betöltése…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Egy alkalmazás sem található a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre."</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"A telefon elforgatásakor"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A jelenlegi kijelzőbeállítások nem teszik lehetővé az elforgatást"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ikon hozzáadása a kezdőképernyőhöz"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Új alkalmazásoknál"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eltávolítás"</string>
<string name="abandoned_search" msgid="891119232568284442">"Keresés"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index ea3b9dc..f3a034f 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Կրկնակի հպեք և պահեք՝ վիջեթ ավելացնելու համար կամ օգտվեք հարմարեցրած գործողություններից:"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Հպեք և պահեք՝ գլխավոր էկրանին ավելացնելու համար"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Ավելացնել ավտոմատ կերպով"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Հավելվածների որոնում"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Հավելվածների բեռնում…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Ցուցադրման ընթացիկ կարգավորումներն արգելում են պտտումը"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ավելացնել պատկերակը Հիմնական էկրանին"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Նոր հավելվածների համար"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Հեռացնել"</string>
<string name="abandoned_search" msgid="891119232568284442">"Գտնել"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 4c826ea..c56fc2b 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketuk dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Sentuh & tahan untuk ditempatkan di layar utama"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Tempatkan otomatis"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Telusuri Apps"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Memuat Aplikasi..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Tidak ditemukan Aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan layar Utama diputar"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Setelan Tampilan Saat Ini tidak memungkinkan putaran"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon ke layar Utama"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk aplikasi baru"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Tidak dikenal"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Buang"</string>
<string name="abandoned_search" msgid="891119232568284442">"Telusuri"</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 186c174..249704e 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ýttu tvisvar og haltu fingri á græju til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d á breidd og %2$d á hæð"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Haltu inni til að setja á heimaskjáinn"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Staðsetja sjálfkrafa"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Leita í forritum"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Hleður forrit…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning fyrir heimaskjá"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Þegar símanum er snúið"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Núverandi skjástilling leyfir ekki snúning"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bæta tákni á heimaskjáinn"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Fyrir ný forrit"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Óþekkt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Fjarlægja"</string>
<string name="abandoned_search" msgid="891119232568284442">"Leita"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 6b44c5b..18e28c9 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tocca due volte e tieni premuto per scegliere un widget o per utilizzare azioni personalizzate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Tieni premuto per posizionare l\'elemento nella schermata Home"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Posiziona automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cerca app"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Caricamento di app…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Con il telefono ruotato"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"L\'impostazione corrente del display non consente la rotazione"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Aggiungi icone alla schermata Home"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per le nuove app"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Sconosciuto"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Rimuovi"</string>
<string name="abandoned_search" msgid="891119232568284442">"Cerca"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index e28fb9f..059f849 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"הקש פעמיים וגע נגיעה רציפה בווידג\'ט כדי לבחור בו, או השתמש בפעולות מותאמות אישית."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"רוחב %1$d על גובה %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"גע והחזק כדי למקם במסך דף הבית"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"מקם אוטומטית"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"חפש אפליקציות"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"טוען אפליקציות…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"אפשרות סיבוב של מסך דף הבית"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר הטלפון מסובב"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"הגדרת התצוגה הנוכחית אינה מאפשרת סיבוב"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"הוספת סמל במסך דף הבית"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"לאפליקציות חדשות"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"לא ידוע"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"הסר"</string>
<string name="abandoned_search" msgid="891119232568284442">"חפש"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index fc058e4..f45af77 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ダブルタップ後に押し続けてウィジェットを選択するか、カスタム操作を使用してください。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"幅 %1$d、高さ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"押し続けると、ホーム画面に追加できます"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"自動的に追加"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"アプリを検索"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"アプリを読み込んでいます…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンが回転したとき"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"現在の [ディスプレイ] 設定では回転を使用できません"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ホーム画面にアイコンを追加"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたときに"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"削除"</string>
<string name="abandoned_search" msgid="891119232568284442">"検索"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index f2c480d..21f440b 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ორმაგად შეეხეთ და გეჭიროთ ვიჯეტის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"სიგრძე: %1$d, სიგანე: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ხანგრძლივად შეეხეთ მთავარ ეკრანზე განსათავსებლად"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"ავტომატურად განთავსება"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"აპების ძიება"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"აპები იტვირთება..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ტელეფონის შეტრიალებისას"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ბრუნვა დაუშვებელია ჩვენების მიმდინარე პარამეტრებით"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ხატულას მთავარ ეკრანზე დამატება"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ახალი აპებისთვის"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ამოშლა"</string>
<string name="abandoned_search" msgid="891119232568284442">"ძიება"</string>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index 1919ac1..7fc61b9 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Виджетті таңдау немесе арнаулы әрекеттерді таңдау үшін екі рет түртіп, ұстап тұрыңыз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ені: %1$d, биіктігі: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Басып тұрып, негізгі экранда қойылатын жерге апарыңыз"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Автоматты қою"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Қолданбаларды іздеу"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Қолданбалар жүктелуде…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"«<xliff:g id="QUERY">%1$s</xliff:g>» сұрауына сәйкес келетін қолданбалар жоқ"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бұрылғанда"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранның ағымдағы параметрі айналуға рұқсат бермейді"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Негізгі экранға белгіше енгізу"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңа қолданбаларға арналған"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Белгісіз"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Алып тастау"</string>
<string name="abandoned_search" msgid="891119232568284442">"Іздеу"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 40f4702..8b271e5 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ប៉ះពីរដង ហើយចុចឲ្យជាប់ដើម្បីជ្រើសយកធាតុក្រាហ្វិក ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"សង្កត់ឲ្យជាប់ដើម្បីដាក់វានៅលើអេក្រង់ដើម"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"ដាក់ដោយស្វ័យប្រវត្តិ"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ស្វែងរកកម្មវិធី"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"កំពុងដំណើរការកម្មវិធី..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"គ្មានកម្មវិធីដែលត្រូវជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ការកំណត់អេក្រង់បច្ចុប្បន្នមិនអនុញ្ញាតការបង្វិលទេ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"បញ្ចូលរូបតំណាងទៅអេក្រង់ដើម"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"សម្រាប់កម្មវិធីថ្មី"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"មិនស្គាល់"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"លុបចេញ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ស្វែងរក"</string>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 1c29c74..209bdab 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ವಿಜೆಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ಮುಖಪುಟ ಪರದೆಯ ಮೇಲೆ ಇಡಲು ಟಚ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಇಡಿ"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ಅಪ್ಲಿಕೇಷನ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್ ತಿರುಗಿಸಿದಾಗ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ಪ್ರಸ್ತುತ ಪ್ರದರ್ಶನ ಸೆಟ್ಟಿಂಗ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ಅಪರಿಚಿತ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ತೆಗೆದುಹಾಕಿ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ಹುಡುಕಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index cede509..08b73f8 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"위젯을 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 액션을 사용합니다."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"너비 %1$d, 높이 %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"길게 터치하여 홈 화면에 추가"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"자동으로 추가"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"앱 검색"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"앱 로드 중..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'와(과) 일치하는 앱이 없습니다."</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"휴대전화 회전 시"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"현재 표시 설정에는 회전 기능이 허용되지 않습니다."</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"홈 화면에 아이콘 추가"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"새로 설치한 앱에 적용"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"알 수 없음"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"삭제"</string>
<string name="abandoned_search" msgid="891119232568284442">"검색"</string>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 8e02c3b..e5465aa 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Виджет тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Туурасы: %1$d, бийиктиги: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Басып туруп, башкы экранга сүйрөп барып, таштаңыз"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Автоматтык түрдө жайгаштыруу"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Колдонмолорду издөө"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Колдонмолор жүктөлүүдө…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" дал келген колдонмолор табылган жок"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон айланганда"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранды айлантуу параметри өчүрүлгөн"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Башкы экранга сүрөтчө кошуу"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңы колдонмолор үчүн"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Белгисиз"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Алып салуу"</string>
<string name="abandoned_search" msgid="891119232568284442">"Издөө"</string>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 3d39ccf..7783c7a 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ແຕະຄ້າງໄວ້ ເພື່ອເລືອກວິດເຈັດ ຫຼື ໃຊ້ການດຳເນີນການກຳນົດເອງ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ກວ້າງ %1$d ຄູນສູງ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ແຕະຄ້າງໄວ້ເພື່ອວາງໄວ້ໜ້າຫຼັກ"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"ວາງອັດຕະໂນມັດ"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ຊອກຫາແອັບ"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ກຳລັງໂຫລດແອັບ..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"ບໍ່ພົບແອັບໃດທີ່ກົງກັນ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ການຕັ້ງຄ່າສະແດງຜົນປັດຈຸບັນບໍ່ອະນຸຍາດໃຫ້ໝຸນໄດ້"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ສຳລັບແອັບໃໝ່"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ບໍ່ຮູ້ຈັກ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 3f075fb..b44549a 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dukart palieskite ir laikykite, kad pasirinktumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Palieskite ir palaikykite, kad padėtumėte pagrindiniame ekrane"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Padėti automatiškai"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Ieškoti programų"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Įkeliamos programos..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Leisti pasukti pagrindinį ekraną"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kai telefonas pasukamas"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Naudojant dabartinį pateikties nustatymą neleidžiama pasukti"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridėti piktogr. prie pagrindinio ekrano"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Skirta naujoms programoms"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nežinoma"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Pašalinti"</string>
<string name="abandoned_search" msgid="891119232568284442">"Ieškoti"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 57f5f78..a623294 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Lai atlasītu logrīku, veiciet dubultskārienu uz tā un turiet to vai arī veiciet pielāgotas darbības."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Sākuma ekrānā pieskarieties kādai vietai un turiet"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Novietot automātiski"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Meklēt lietotnes"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Notiek lietotņu ielāde…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne."</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Atļaut sākuma ekrāna pagriešanu"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Pagriežot tālruni"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Pašreizējā displeja iestatījumā nav atļauta pagriešana."</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pievienot ikonu sākuma ekrānā"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Jaunām lietotnēm"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nezināma"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Noņemt"</string>
<string name="abandoned_search" msgid="891119232568284442">"Meklēt"</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index f82b39a..e6ca38f 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Допрете двапати и задржете за да изберете додаток или да користите приспособени дејства."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d широк на %2$d висок"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Допрете и задржете за да поставите на почетниот екран"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Постави автоматски"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пребарување апликации"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Се вчитуваат апликации…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволете ротација на Почетниот екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Кога телефонот се ротира"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Тековната поставка на Екранот не дозволува ротација"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додајте икона на почетниот екран"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови апликации"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Отстрани"</string>
<string name="abandoned_search" msgid="891119232568284442">"Барај"</string>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index d1185c1..8ec29d3 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"വിജറ്റ് തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d വീതിയും %2$d ഉയരവും"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ഹോം സ്ക്രീനിൽ സ്ഥാപിക്കാൻ സ്പർശിച്ച് പിടിക്കുക"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"സ്വയമേവ സ്ഥാപിക്കുക"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ആപ്പുകളെ തിരയുക"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ആപ്പ്സ് ലോഡുചെയ്യുന്നു..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പ്സൊന്നും കണ്ടെത്തിയില്ല"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"നിലവിലെ ഡിസ്പ്ലേ ക്രമീകരണം തിരിക്കൽ അനുവദിക്കുന്നില്ല"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ഹോം സ്ക്രീനിലേക്ക് ഐക്കൺ ചേർക്കുക"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"പുതിയ ആപ്പുകൾക്ക്"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"അജ്ഞാതം"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"നീക്കംചെയ്യുക"</string>
<string name="abandoned_search" msgid="891119232568284442">"തിരയുക"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 7b70aae..c8dfdd5 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Жижиг хэрэгсэл авах болон тохируулсан үйлдлийг ашиглахын тулд 2 удаа товшоод барина уу."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d өргөн %2$d өндөр"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Нүүр дэлгэцэд байршуулахын тулд дараад, хүлээнэ үү"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Автоматаар байршуулах"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Апп хайх"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Аппликейшныг ачаалж байна..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д нийцэх апп олдсонгүй"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Утсыг эргүүлсэн үед"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Дэлгэцийн одоогийн тохиргоогоор эргүүлэх боломжгүй"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Нүүр хуудаст дүрс тэмдэг нэмэх"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Шинэ аппад зориулсан"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Устгах"</string>
<string name="abandoned_search" msgid="891119232568284442">"Хайх"</string>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index c8e6377..4056b03 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा सानुकूल क्रिया वापरा."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"मुख्यपृष्ठावर ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"स्वयंचलितपणे ठेवा"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"अॅप्स शोधा"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"अॅप्स लोड करीत आहे..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्यास अनुमती द्या"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरविला जातो तेव्हा"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग फिरविण्यास परवानगी देत नाही"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"मुख्य स्क्रीनवर चिन्ह जोडा"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"काढा"</string>
<string name="abandoned_search" msgid="891119232568284442">"शोधा"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 45410f3..9ec1813 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketik dua kali & tahan untuk mengambil widget atau menggunakan tindakan tersuai"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Lebar %1$d kali tinggi %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Sentuh & tahan untuk meletakkan pada skrin utama"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Letakkan secara automatik"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cari Apl"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Memuatkan Apl…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Tiada Apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Benarkan putaran Skrin Utama"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Apabila telefon diputar"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Tetapan Paparan semasa tidak membenarkan putaran"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon pada Skrin Utama"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk apl baharu"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Tidak diketahui"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Alih keluar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Carian"</string>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index e79ff88..5da5f65 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ဝစ်ဂျက်တစ်ခုကိုရယူရန် သို့မဟုတ် စိတ်ကြိုက်လုပ်ဆောင်မှုများကို အသုံးပြုရန် နှစ်ချက်တို့ပြီး ကိုင်ထားပါ။"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"အလျား %1$d နှင့် အမြင့် %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ပင်မစာမျက်နှာတွင် ထားရန် ထိပြီး ဖိထားပါ"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"အလိုအလျောက် ထားရန်"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ရှာဖွေမှု အက်ပ်များ"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"အက်ပ်များ ရယူနေစဉ်..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ဖ်များမတွေ့ပါ"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ဖုန်းကိုလှည့်ထားစဉ်"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"လက်ရှိ မြင်ကွင်းဆက်တင်တွင် မြင်ကွင်းကို လှည့်ခွင့်မပေးပါ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"အက်ပ်အသစ်များအတွက်"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ဖယ်ရှားရန်"</string>
<string name="abandoned_search" msgid="891119232568284442">"ရှာဖွေရန်"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 591c626..694c6fc 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dobbelttrykk og hold inne for å velge en modul eller bruke tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Trykk og hold for å plassere på startskjermen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Plassér automatisk"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Søk i apper"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Laster inn apper …"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillat rotasjon av startskjermen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Med den nåværende skjerminnstillingen støttes ikke rotasjon"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Legg til ikon på startsiden"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apper"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ukjent"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Fjern"</string>
<string name="abandoned_search" msgid="891119232568284442">"Søk"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index 91b1e1b..01ec5bd 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"विजेटलाई छान्न वा आफू अनुकूल कार्यहरू प्रयोग गर्न डबल ट्याप गरी होल्ड गर्नुहोस्।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौडाइ गुणा %2$d उचाइ"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"गृह स्क्रिनमा राख्न छुनुहोस् र थिची राख्नुहोस्"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"स्वतः राख्नुहोस्"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"अनुप्रयोगहरू खोज्नुहोस्"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"अनुप्रयोगहरू लोड गरिँदै..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै अनुप्रयोगहरू फेला परेनन्"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोनलाई घुमाइँदा"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"हालको प्रदर्शन सम्बन्धी सेटिङले घुमाउने सुविधालाई अनुमति दिँदैन"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"गृह स्क्रिनमा आइकन थप्नुहोस्"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ अनुप्रयोगका लागि"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"हटाउनुहोस्"</string>
<string name="abandoned_search" msgid="891119232568284442">"खोजी गर्नुहोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 4223743..a477893 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dubbeltik en blijf aanraken om een widget toe te voegen of aangepaste acties te gebruiken."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Tik op een item en houd dit vast om het op het startscherm te plaatsen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Automatisch plaatsen"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Apps zoeken"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Apps laden…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Draaien van startscherm toestaan"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer de telefoon gedraaid is"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Huidige scherminstelling staat draaien niet toe"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pictogram toevoegen aan startscherm"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Voor nieuwe apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Verwijderen"</string>
<string name="abandoned_search" msgid="891119232568284442">"Zoeken"</string>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index c1192c5..71d9942 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"ਡਬਲ-ਟੈਪ & ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਹੋਲਡ ਕਰੋ ਅਤੇ ਕਸਟਮ ਕਿਰਿਆਵਾਂ ਵਰਤੋ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ਮੁੱਖ ਸਕ੍ਰੀਨ \'ਤੇ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"ਸਵੈਚਲਿਤ ਤਰੀਕੇ ਨਾਲ ਰੱਖੋ"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ਐਪਸ ਖੋਜੋ"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮਿਲਦੀਆਂ ਕੋਈ ਵੀ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ਮੁੱਖ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ਵਰਤਮਾਨ ਡਿਸਪਲੇ ਸੈਟਿੰਗ ਘੁੰਮਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦੀ ਹੈ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ਮੁੱਖ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ਅਗਿਆਤ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ਹਟਾਓ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ਖੋਜੋ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index ed60ee3..4225d37 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Kliknij dwukrotnie i przytrzymaj, by wybrać widżet lub użyć działań niestandardowych."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Kliknij i przytrzymaj, by umieścić na ekranie głównym"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Umieść automatycznie"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Szukaj w aplikacjach"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Wczytuję aplikacje…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Zezwalaj na obrót ekranu głównego"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Po obróceniu telefonu"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Obecne ustawienia wyświetlania nie pozwalają na obrót ekranu"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonę do ekranu głównego"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"W przypadku nowych aplikacji"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Brak informacji"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Usuń"</string>
<string name="abandoned_search" msgid="891119232568284442">"Szukaj"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 37e16aa..4754bb8 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toque duas vezes sem soltar para escolher um widget ou utilize ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Toque sem soltar para colocar no ecrã principal"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Colocar automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pesquisar aplicações"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"A carregar aplicações..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Não foram encontradas aplic. que correspondam a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação do ecrã principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o telemóvel é rodado"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A definição de visualização atual não permite a rotação"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone ao ecrã principal"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicações"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index b142e6c..2f15b40 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toque duas vezes e segure para selecionar um widget ou usar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Toque e segure-o para posicionar na tela inicial"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Posicionar automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pesquisar apps"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Carregando apps…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação da tela inicial"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o smartphone for girado"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"A configuração atual de exibição não permite rotação"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone à tela inicial"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novos apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 3d92993..8bb73f2 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Atingeți de două ori și mențineți apăsat ca să alegeți un widget sau folosiți acțiuni personalizate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Atingeți lung pentru a plasa pe ecranul de pornire"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Plasare automată"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Căutați aplicații"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Se încarcă aplicațiile..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Permiteți rotirea ecranului de pornire"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Când telefonul este rotit"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Setarea actuală a afișajului nu permite rotirea"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adaugă pictograme în ecranul de pornire"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pentru aplicații noi"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Necunoscut"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminați"</string>
<string name="abandoned_search" msgid="891119232568284442">"Căutați"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 0e2fc96..bfecf59 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Чтобы выбрать виджет, нажмите на него дважды и не отпускайте или выполните предложенные действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d, высота %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Нажмите и удерживайте, чтобы добавить на главный экран"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Добавить на главный экран автоматически"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Поиск приложений"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Загрузка…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешить поворачивать главный экран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Когда телефон повернут"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"В настройках отключен поворот экрана"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавлять значки"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Добавлять значки установленных приложений на главный экран."</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Неизвестно"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Удалить"</string>
<string name="abandoned_search" msgid="891119232568284442">"Найти"</string>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 5bfd10c..a5d34ca 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"විජට් එකක් අහුලා ගැනීමට හෝ අභිරුචි ක්රියා කිරීමට ඩබල් ටැප් කර අල්ලා ගෙන සිටින්න."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"පළල %1$d උස %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"මුල් පිටු තිරයෙහි තැබීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"ස්වයංක්රියව තබන්න"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"යෙදුම් සෙවීම"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"යෙදුම් පූරණය වෙමින්…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"දුරකථනය කරකවන විට"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"වත්මන් සංදර්ශක සැකසීම් කරකැවීමට සහාය නොදක්වයි"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"නව යෙදුම් සඳහා"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"නොදනී"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ඉවත් කරන්න"</string>
<string name="abandoned_search" msgid="891119232568284442">"සොයන්න"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index cc95676..239bf29 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Miniaplikáciu pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Klepnutím a podržaním umiestníte na plochu"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Umiestniť automaticky"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Hľadať aplikácie"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Načítavajú sa aplikácie..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Povoliť otáčanie plochy"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Pri otočení telefónu"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuálne nastavenie obrazovky nepovoľuje otáčanie"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridať ikonu na plochu"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pri inštalácii novej aplikácie"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Neznáme"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Odstrániť"</string>
<string name="abandoned_search" msgid="891119232568284442">"Vyhľadať"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 4bbefaa..b245c54 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Če želite izbrati pripomoček ali uporabiti dejanja po meri, se ga dvakrat dotaknite in ga pridržite."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Dotaknite se elementa in ga pridržite, da ga postavite na začetni zaslon"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Postavi samodejno"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Iskanje po aplikacijah"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Nalaganje aplikacij …"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Omogočanje sukanja začetnega zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ko se telefon zasuka"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutna nastavitev zaslona ne dovoljuje sukanja"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikono na začetni zaslon"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Neznano"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Odstrani"</string>
<string name="abandoned_search" msgid="891119232568284442">"Iskanje"</string>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index 2c6c8d6..4adac7f 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Prek dy herë dhe mbaj shtypur për të zgjedhur një miniaplikacion ose për të përdorur veprimet e personalizuara."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i gjerë me %2$d i lartë"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Prek dhe mbaj të shtypur për të vendosur në ekranin bazë"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Vendos automatikisht"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Kërko për aplikacione"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Po ngarkon aplikacionet..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit kryesor"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kur telefoni rrotullohet"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cilësimi aktuali i afishimit nuk lejon rrotullimin"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Shto ikonë në ekranin bazë"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Për aplikacionet e reja"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"I panjohur"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Hiq"</string>
<string name="abandoned_search" msgid="891119232568284442">"Kërko"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 086b9fa..f6a28da 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Двапут додирните и задржите да бисте изабрали виџет или користите прилагођене радње."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ширина од %1$d и висина од %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Додирните и задржите да бисте поставили на почетни екран"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Постави аутоматски"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Претражите апликације"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Апликације се учитавају..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротацију почетног екрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Када се телефон ротира"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Актуелно подешавање приказа не дозвољава ротацију"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додај икону на почетни екран"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нове апликације"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Уклони"</string>
<string name="abandoned_search" msgid="891119232568284442">"Претражи"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 255381a..c740167 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryck två gånger och håll kvar om du vill ta upp en widget eller använda anpassade åtgärder."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Placera på startskärmen genom att trycka länge"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Placera automatiskt"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sök efter appar"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Läser in appar …"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Det gick inte att hitta några appar som matchar <xliff:g id="QUERY">%1$s</xliff:g>"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillåt rotering av startskärmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"När mobilen vrids"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Rotering tillåts inte i de nuvarande skärminställningarna"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lägg till ikonen på startskärmen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"För nya appar"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Okänt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ta bort"</string>
<string name="abandoned_search" msgid="891119232568284442">"Sök"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 76a1487..0c677ec 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Gonga mara mbili na ushikilie ile uchague wijeti au utumie vitendo maalum."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Gusa na ushikilie ili uweke kwenye skrini ya kwanza"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Weka kiotomatiki"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tafuta Programu"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Inapakia Programu..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Haikupata programu zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -79,6 +77,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Ruhusu kuzungusha skrini ya Kwanza"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Simu inapozungushwa"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Mipangilio ya sasa ya sehemu ya Onyesho hairuhusu kuzungusha"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ongeza aikoni kwenye Skrini ya kwanza"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwa ajili ya programu mpya"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Yasiyojulikana"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ondoa"</string>
<string name="abandoned_search" msgid="891119232568284442">"Tafuta"</string>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index 49658dd2..15e0c20 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"விட்ஜெட்டைத் தேர்ந்தெடுக்க இருமுறை தட்டிப் பிடிக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d அகலத்திற்கு %2$d உயரம்"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"முகப்புத் திரையில் சேர்க்க, அதைத் தொட்டுப் பிடித்திருக்கவும்"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"தானாகவே சேர்"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"பயன்பாடுகளில் தேடுக"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"பயன்பாடுகளை ஏற்றுகிறது..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"மொபைலைச் சுழற்றும் போது"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"தற்போதைய திரை அமைப்பு சுழற்றுவதை அனுமதிக்கவில்லை"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"முகப்புத் திரையில் ஐகானைச் சேர்"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"புதிய பயன்பாடுகளுக்கு"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"தெரியாதது"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"அகற்று"</string>
<string name="abandoned_search" msgid="891119232568284442">"தேடு"</string>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index f42309d..9c1c3e1 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"విడ్జెట్ను ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి, ఉంచండి."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"హోమ్ స్క్రీన్లో ఉంచడానికి నొక్కి & పట్టుకోండి"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"స్వయంచాలకంగా ఉంచండి"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"అనువర్తనాలను శోధించండి"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"అనువర్తనాలను లోడ్ చేస్తోంది…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అనువర్తనాలేవీ కనుగొనబడలేదు"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ఫోన్ను తిప్పినప్పుడు"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ప్రస్తుత డిస్ప్లే సెట్టింగ్ భ్రమణాన్ని అనుమతించలేదు"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"హోమ్ స్క్రీన్కి చిహ్నాన్ని జోడించు"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"కొత్త అనువర్తనాల కోసం"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"తెలియదు"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"తీసివేయి"</string>
<string name="abandoned_search" msgid="891119232568284442">"శోధించు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index ef67660..39c60aa 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"แตะ 2 ครั้งค้างไว้เพื่อเลือกวิดเจ็ตหรือใช้การกระทำที่กำหนดเอง"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"กว้าง %1$d x สูง %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"แตะค้างไว้เพื่อวางบนหน้าจอหลัก"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"วางโดยอัตโนมัติ"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ค้นหาแอป"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"กำลังโหลดแอป…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"อนุญาตให้หมุนหน้าจอหลัก"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"เมื่อหมุนโทรศัพท์"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"การตั้งค่าการแสดงผลปัจจุบันไม่อนุญาตให้มีการหมุน"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"เพิ่มไอคอนในหน้าจอหลัก"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"สำหรับแอปใหม่"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ไม่รู้จัก"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ลบ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ค้นหา"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 50b0df3..1838865 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"I-double tap nang matagal upang pumili ng widget o gumamit ng mga custom na pagkilos."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Pindutin nang matagal upang ilagay sa home screen"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Awtomatikong ilagay"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Mga App sa Paghahanap"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Nilo-load ang Mga App…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Walang nakitang Mga App na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Payagan ang pag-rotate ng Home screen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kailan maro-rotate ang telepono"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Hindi pinahihintulutan ng kasalukuyang setting ng Display ang pag-rotate"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Idagdag ang icon sa Home screen"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para sa mga bagong app"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Hindi kilala"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Alisin"</string>
<string name="abandoned_search" msgid="891119232568284442">"Maghanap"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 296de0f..6136082 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Bir widget\'ı seçmek veya özel işlemleri kullanmak için iki kez hafifçe dokunun ve basılı tutun."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Ana ekrana yerleştirmek için dokunun ve basılı tutun"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Otomatik olarak yerleştir"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Uygulamalarda Ara"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Uygulamalar Yükleniyor…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Ana ekranı döndürmeye izin ver"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon döndürüldüğünde"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Mevcut Ekran ayarı, döndürmeye izin vermiyor"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ana ekrana simge ekle"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni uygulamalar için"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Bilinmiyor"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Kaldır"</string>
<string name="abandoned_search" msgid="891119232568284442">"Ara"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 0d6c6bc..bc36a50 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Двічі натисніть і утримуйте, щоб вибрати віджет, або виконайте іншу дію."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина – %1$d, висота – %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Натисніть і утримуйте, щоб додати на головний екран"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Додати автоматично"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пошук додатків"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Завантаження додатків…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволити обертання головного екрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Коли телефон обертається"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Поточні налаштування дисплея не підтримують обертання"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додати значок на головний екран"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для нових додатків"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Невідомо"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Видалити"</string>
<string name="abandoned_search" msgid="891119232568284442">"Шукати"</string>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index e7a1af8..0bd45c8 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"کوئی ویجٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور پکڑے رکھیں۔"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d چوڑا اور %2$d اونچا"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"ہوم اسکرین پر رکھنے کیلئے ٹچ کریں اور دبائے رکھیں"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"خودکار طور پر رکھیں"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ایپس تلاش کریں"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"ایپس لوڈ ہو رہی ہیں…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"جب فون گھمایا جاتا ہے"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"موجودہ ڈسپلے ترتیب گھمانے کی اجازت نہیں دیتی"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"آئیکن کو ہوم اسکرین میں شامل کریں"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"نئی ایپس کیلئے"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"نامعلوم"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ہٹائیں"</string>
<string name="abandoned_search" msgid="891119232568284442">"تلاش کریں"</string>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 0f85353..fd5d013 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Eni %1$d, bo‘yi %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Bosh ekranga chiqarish uchun bosib turing"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Avtomatik joylashtirish"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Ilovalar ichidan qidirish"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Ilovalar yuklanmoqda…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"“<xliff:g id="QUERY">%1$s</xliff:g>” so‘rovi bo‘yicha hech narsa topilmadi"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Asosiy ekranni aylantirishga ruxsat berish"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon burilganda"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Ekran sozlamalariga ko‘ra uni aylantirib bo‘lmaydi"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bosh ekranga ikonka qo‘shish"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Noma’lum"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"O‘chirish"</string>
<string name="abandoned_search" msgid="891119232568284442">"Qidirish"</string>
diff --git a/res/values-v26/bools.xml b/res/values-v26/bools.xml
index 1093f78..30537fe 100644
--- a/res/values-v26/bools.xml
+++ b/res/values-v26/bools.xml
@@ -18,4 +18,6 @@
<resources>
<bool name="notification_badging_enabled">true</bool>
+
+ <bool name="enable_install_shortcut_api">false</bool>
</resources>
\ No newline at end of file
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index d83ba54..9b9d04c 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Nhấn đúp và giữ để chọn tiện ích hoặc sử dụng tác vụ tùy chỉnh."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Chạm và giữ để đặt lên màn hình chính"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Tự động đặt"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tìm kiếm ứng dụng"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Đang tải ứng dụng..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Cho phép xoay Màn hình chính"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Khi xoay điện thoại"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cài đặt Hiển thị hiện tại không cho phép xoay"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Thêm biểu tượng vào màn hình chính"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Cho ứng dụng mới"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Không xác định"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Xóa"</string>
<string name="abandoned_search" msgid="891119232568284442">"Tìm kiếm"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index c037948..545bf4a 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"点按两次并按住小部件即可选择小部件,您也可以使用自定义操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"宽 %1$d,高 %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"触摸并按住即可放在主屏幕上"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"自动放置"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"搜索应用"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"正在加载应用…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"允许旋转主屏幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"手机旋转时"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"当前的显示设置不允许旋转设备"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"将图标添加到主屏幕"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"适用于新应用"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"未知"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜索"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 15a62e5..7afb3ae 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"連扲兩下,然後扲住,就可以新增小工具,或者執行自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d 闊,%2$d 高"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"輕觸並按住即可放在主畫面上"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"自動放置"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"搜尋應用程式"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"正在載入應用程式…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"無法找到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"允許主畫面旋轉"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"「目前顯示屏」設定不允許旋轉"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主畫面"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 3d77283..4425c66 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"輕觸兩下並按住小工具即可選取,您也可以使用自訂動作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"寬度為 %1$d,高度為 %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"按住即可放在主螢幕上"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"自動放置"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"搜尋應用程式"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"正在載入應用程式…"</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"找不到符合「<xliff:g id="QUERY">%1$s</xliff:g>」的應用程式"</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主螢幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"目前的顯示設定不允許旋轉畫面"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主螢幕"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index edbb64d..0be9ebc 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -33,10 +33,8 @@
<string name="long_accessible_way_to_add" msgid="4289502106628154155">"Thepha kabili bese uyabamba ukuze uthathe iwijethi noma sebenzisa izenzo ezingokwezifiso."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string>
- <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
- <skip />
- <!-- no translation found for place_automatically (1502491650329146581) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="8662194377800507270">"Thinta uphinde ubambe ukuze ubeke kusikrini sasekhaya"</string>
+ <string name="place_automatically" msgid="1502491650329146581">"Beka ngokuzenzakalela"</string>
<string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sesha Izinhlelo Zokusebenza"</string>
<string name="all_apps_loading_message" msgid="7557140873644765180">"Ilayisha izinhlelo zokusebenza..."</string>
<string name="all_apps_no_search_results" msgid="6332185285860416787">"Azikho izinhlelo zokusebenza ezitholakele ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
@@ -77,6 +75,8 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"Vumela ukuphendukiswa kwesikrini sasekhaya"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Uma ifoni iphendukiswa"</string>
<string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Isilungiselelo sesiboniso samanje asivumeli ukuzungezisa"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engeza isithonjana eskrinini sasekhaya"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwezinhlelo zokusebenza ezintsha"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Akwaziwa"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Susa"</string>
<string name="abandoned_search" msgid="891119232568284442">"Sesha"</string>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index cc4a7ba..53c67e2 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -18,4 +18,6 @@
<resources>
<bool name="notification_badging_enabled">false</bool>
+
+ <bool name="enable_install_shortcut_api">true</bool>
</resources>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index a02df16..83a44d7 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -36,4 +36,9 @@
<color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
<color name="notification_icon_default_color">#757575</color> <!-- Gray 600 -->
+ <color name="notification_header_background_color">#F5F5F5</color> <!-- Gray 100 -->
+ <color name="notification_background_color">#FFF</color>
+ <color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 -->
+ <color name="divider_color">@color/notification_color_beneath</color>
+ <color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index cb813d5..745bce3 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -72,16 +72,15 @@
filter the activities shown in the launcher. Can be empty. -->
<string name="app_filter_class" translatable="false"></string>
- <!-- List of package names that com.android.launcher3.action.LAUNCH
- should be targeting. Can be empty. -->
- <array name="launch_broadcast_targets" translatable="false"></array>
-
<!-- Name of an icon provider class. -->
<string name="icon_provider_class" translatable="false"></string>
<!-- Name of a drawable factory class. -->
<string name="drawable_factory_class" translatable="false"></string>
+ <!-- Name of a user event dispatcher class. -->
+ <string name="user_event_dispatcher_class" translatable="false"></string>
+
<!-- Package name of the default wallpaper picker. -->
<string name="wallpaper_picker_package" translatable="false"></string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 517bf9f..132ae07 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -150,10 +150,9 @@
<!-- Deep shortcuts -->
<dimen name="deep_shortcuts_elevation">9dp</dimen>
- <dimen name="bg_pill_width">208dp</dimen>
- <dimen name="bg_pill_height">48dp</dimen>
- <dimen name="bg_pill_radius">24dp</dimen>
- <dimen name="deep_shortcuts_spacing">4dp</dimen>
+ <dimen name="bg_popup_item_width">208dp</dimen>
+ <dimen name="bg_popup_item_height">48dp</dimen>
+ <dimen name="popup_items_spacing">4dp</dimen>
<dimen name="pre_drag_view_scale">6dp</dimen>
<!-- an icon with shortcuts must be dragged this far before the container is removed. -->
<dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
@@ -171,25 +170,35 @@
deep_shortcut_padding_end + deep_shortcut_drag_handle_size / 2 - deep_shortcuts_arrow_width / 2
also happens to equal 19dp-->
<dimen name="deep_shortcuts_arrow_horizontal_offset">19dp</dimen>
+ <!-- popup_item_width - icon_size - padding_start - drawable_padding -->
+ <dimen name="deep_shortcuts_divider_width">158dp</dimen>
<!-- Icon badges (with notification counts) -->
<dimen name="badge_size">24dp</dimen>
<dimen name="badge_text_size">12dp</dimen>
- <dimen name="badge_small_padding">1dp</dimen>
+ <dimen name="badge_small_padding">0dp</dimen>
<dimen name="badge_large_padding">3dp</dimen>
- <dimen name="notification_icon_size">28dp</dimen>
- <dimen name="notification_footer_icon_size">24dp</dimen>
- <!-- (icon_size - secondary_icon_size) / 2 -->
+ <dimen name="notification_icon_size">24dp</dimen>
+ <dimen name="notification_footer_icon_size">18dp</dimen>
<!-- Notifications -->
- <dimen name="notification_footer_icon_row_padding">2dp</dimen>
- <dimen name="notification_icon_margin_start">8dp</dimen>
- <dimen name="notification_text_margin_start">8dp</dimen>
- <dimen name="notification_footer_height">36dp</dimen>
- <!-- The height to use when there are no icons in the footer -->
- <dimen name="notification_footer_collapsed_height">@dimen/bg_pill_radius</dimen>
+ <dimen name="bg_round_rect_radius">12dp</dimen>
+ <dimen name="notification_padding">12dp</dimen>
+ <!-- notification_padding + (icon_size - footer_icon_size) / 2 -->
+ <dimen name="notification_footer_icon_row_padding">15dp</dimen>
+ <dimen name="notification_header_padding_after_count">8dp</dimen>
+ <dimen name="notification_header_height">32dp</dimen>
+ <dimen name="notification_main_height">60dp</dimen>
+ <dimen name="notification_footer_height">@dimen/bg_popup_item_height</dimen>
+ <dimen name="notification_header_text_size">12dp</dimen>
+ <dimen name="notification_main_text_size">14dp</dimen>
+ <!-- notification_icon_size + notification+padding + padding we want between icon and text -->
+ <dimen name="notification_main_text_padding_end">40dp</dimen>
<dimen name="notification_elevation">2dp</dimen>
- <dimen name="notification_divider_height">0.5dp</dimen>
+ <dimen name="horizontal_ellipsis_size">18dp</dimen>
+ <!-- arrow_horizontal_offset - (ellipsis_size - arrow_width) / 2 -->
+ <dimen name="horizontal_ellipsis_offset">15dp</dimen>
+ <dimen name="popup_item_divider_height">0.5dp</dimen>
<dimen name="swipe_helper_falsing_threshold">70dp</dimen>
<!-- Other -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c1280c7..423a772 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -72,7 +72,10 @@
The text must fit in the size of a small icon [CHAR_LIMIT=3] -->
<string name="deep_notifications_overflow" translatable="false">+%1$d</string>
<!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
- <string name="notifications_header" translatable="false">Notifications</string>
+ <plurals name="notifications_header" translatable="false">
+ <item quantity="one">Notification</item>
+ <item quantity="other">Notifications</item>
+ </plurals>
<!-- Drag and drop -->
<skip />
@@ -176,6 +179,11 @@
<!-- 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>
+ <!-- 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>
+ <!-- Text description of the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=NONE] -->
+ <string name="auto_add_shortcuts_description">For new apps</string>
+
<!-- Label on an icon that references an uninstalled package, for which we have no information about when it might be installed. [CHAR_LIMIT=15] -->
<string name="package_state_unknown">Unknown</string>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 624d9eb..a16583d 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -23,4 +23,11 @@
android:persistent="true"
/>
+ <SwitchPreference
+ android:key="pref_add_icon_to_home"
+ android:title="@string/auto_add_shortcuts_label"
+ android:summary="@string/auto_add_shortcuts_description"
+ android:defaultValue="true"
+ android:persistent="true"
+ />
</PreferenceScreen>
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 52a83dc..bd12686 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -95,7 +95,7 @@
return null;
}
- protected static void closeOpenContainer(Launcher launcher, @FloatingViewType int type) {
+ public static void closeOpenContainer(Launcher launcher, @FloatingViewType int type) {
AbstractFloatingView view = getOpenView(launcher, type);
if (view != null) {
view.close(true);
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 9cce9b1..5b42cad 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -208,16 +208,6 @@
}
/**
- * Query the launcher apps service for whether the supplied package has
- * MAIN/LAUNCHER activities in the supplied package.
- */
- static boolean packageHasActivities(Context context, String packageName,
- UserHandle user) {
- final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
- return launcherApps.getActivityList(packageName, user).size() > 0;
- }
-
- /**
* Returns whether <em>apps</em> contains <em>component</em>.
*/
private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 8bf49c2..9ec26e2 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -21,14 +21,11 @@
import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
import android.os.UserHandle;
-import android.util.Log;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageManagerHelper;
-import java.util.ArrayList;
-
/**
* Represents an app in AllAppsView.
*/
@@ -44,10 +41,10 @@
/**
* {@see ShortcutInfo#isDisabled}
*/
- int isDisabled = ShortcutInfo.DEFAULT;
+ public int isDisabled = ShortcutInfo.DEFAULT;
public AppInfo() {
- itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
}
@Override
@@ -59,11 +56,10 @@
* Must not hold the Context.
*/
public AppInfo(Context context, LauncherActivityInfo info, UserHandle user) {
- this(context, info, user, UserManagerCompat.getInstance(context).isQuietModeEnabled(user));
+ this(info, user, UserManagerCompat.getInstance(context).isQuietModeEnabled(user));
}
- public AppInfo(Context context, LauncherActivityInfo info, UserHandle user,
- boolean quietModeEnabled) {
+ public AppInfo(LauncherActivityInfo info, UserHandle user, boolean quietModeEnabled) {
this.componentName = info.getComponentName();
this.container = ItemInfo.NO_ID;
this.user = user;
@@ -74,7 +70,7 @@
isDisabled |= ShortcutInfo.FLAG_DISABLED_QUIET_USER;
}
- intent = makeLaunchIntent(context, info, user);
+ intent = makeLaunchIntent(info);
}
public AppInfo(AppInfo info) {
@@ -83,7 +79,6 @@
title = Utilities.trim(info.title);
intent = new Intent(info.intent);
isDisabled = info.isDisabled;
- iconBitmap = info.iconBitmap;
}
@Override
@@ -99,14 +94,11 @@
return new ComponentKey(componentName, user);
}
- public static Intent makeLaunchIntent(Context context, LauncherActivityInfo info,
- UserHandle user) {
- long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
+ public static Intent makeLaunchIntent(LauncherActivityInfo info) {
return new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setComponent(info.getComponentName())
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- .putExtra(EXTRA_PROFILE, serialNumber);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
}
@Override
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 2e017df..c4086a8 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -195,7 +195,7 @@
try {
return parseLayout(mLayoutId, screenIds);
} catch (Exception e) {
- Log.w(TAG, "Got exception parsing layout.", e);
+ Log.e(TAG, "Error parsing layout: " + e);
return -1;
}
}
@@ -362,7 +362,7 @@
return addShortcut(info.loadLabel(mPackageManager).toString(),
intent, Favorites.ITEM_TYPE_APPLICATION);
} catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Unable to add favorite: " + packageName + "/" + className, e);
+ Log.e(TAG, "Favorite not found: " + packageName + "/" + className);
}
return -1;
} else {
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 9f4f1f9..e1a3ad0 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -21,9 +21,12 @@
import android.content.ContextWrapper;
import android.view.View.AccessibilityDelegate;
+import com.android.launcher3.logging.UserEventDispatcher;
+
public abstract class BaseActivity extends Activity {
protected DeviceProfile mDeviceProfile;
+ protected UserEventDispatcher mUserEventDispatcher;
public DeviceProfile getDeviceProfile() {
return mDeviceProfile;
@@ -33,6 +36,13 @@
return null;
}
+ public final UserEventDispatcher getUserEventDispatcher() {
+ if (mUserEventDispatcher == null) {
+ mUserEventDispatcher = UserEventDispatcher.get(this);
+ }
+ return mUserEventDispatcher;
+ }
+
public static BaseActivity fromContext(Context context) {
if (context instanceof BaseActivity) {
return (BaseActivity) context;
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 107d700..bad7018 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -42,9 +42,9 @@
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.graphics.HolographicOutlineHelper;
-import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.popup.PopupContainerWithArrow;
import java.text.NumberFormat;
@@ -502,15 +502,14 @@
if (mIcon instanceof FastBitmapDrawable) {
BadgeInfo badgeInfo = mLauncher.getPopupDataProvider().getBadgeInfoForItem(itemInfo);
BadgeRenderer badgeRenderer = mLauncher.getDeviceProfile().mBadgeRenderer;
+ PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(mLauncher);
+ if (popup != null) {
+ popup.updateNotificationHeader(badgeInfo, itemInfo);
+ }
((FastBitmapDrawable) mIcon).applyIconBadge(badgeInfo, badgeRenderer, animate);
}
}
- public IconPalette getIconPalette() {
- return mIcon instanceof FastBitmapDrawable ? ((FastBitmapDrawable) mIcon).getIconPalette()
- : null;
- }
-
/**
* Sets the icon for this view based on the layout direction.
*/
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 8d69fe3..8a477d8 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -42,6 +42,7 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
/**
@@ -142,8 +143,8 @@
mCurrentFilter = new ColorMatrix();
}
- DragView.setColorScale(getTextColor(), mSrcFilter);
- DragView.setColorScale(targetColor, mDstFilter);
+ Themes.setColorScaleOnMatrix(getTextColor(), mSrcFilter);
+ Themes.setColorScaleOnMatrix(targetColor, mDstFilter);
ValueAnimator anim1 = ValueAnimator.ofObject(
new FloatArrayEvaluator(mCurrentFilter.getArray()),
mSrcFilter.getArray(), mDstFilter.getArray());
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index e0fcbf0..8179dad 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -105,7 +105,6 @@
private ArrayList<FolderIcon.PreviewBackground> mFolderBackgrounds = new ArrayList<FolderIcon.PreviewBackground>();
FolderIcon.PreviewBackground mFolderLeaveBehind = new FolderIcon.PreviewBackground();
- Paint mFolderBgPaint = new Paint();
private float mBackgroundAlpha;
@@ -501,9 +500,9 @@
cellToPoint(bg.delegateCellX, bg.delegateCellY, mTempLocation);
canvas.save();
canvas.translate(mTempLocation[0], mTempLocation[1]);
- bg.drawBackground(canvas, mFolderBgPaint);
+ bg.drawBackground(canvas);
if (!bg.isClipping) {
- bg.drawBackgroundStroke(canvas, mFolderBgPaint);
+ bg.drawBackgroundStroke(canvas);
}
canvas.restore();
}
@@ -513,7 +512,7 @@
mFolderLeaveBehind.delegateCellY, mTempLocation);
canvas.save();
canvas.translate(mTempLocation[0], mTempLocation[1]);
- mFolderLeaveBehind.drawLeaveBehind(canvas, mFolderBgPaint);
+ mFolderLeaveBehind.drawLeaveBehind(canvas);
canvas.restore();
}
}
@@ -528,7 +527,7 @@
cellToPoint(bg.delegateCellX, bg.delegateCellY, mTempLocation);
canvas.save();
canvas.translate(mTempLocation[0], mTempLocation[1]);
- bg.drawBackgroundStroke(canvas, mFolderBgPaint);
+ bg.drawBackgroundStroke(canvas);
canvas.restore();
}
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index c9e3d4f..43f7d23 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -32,6 +32,7 @@
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.badge.BadgeRenderer;
+import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
@@ -530,10 +531,13 @@
workspacePadding.bottom);
workspace.setPageSpacing(getWorkspacePageSpacing());
- View qsbContainer = launcher.getQsbContainer();
- lp = (FrameLayout.LayoutParams) qsbContainer.getLayoutParams();
- lp.topMargin = mInsets.top + workspacePadding.top;
- qsbContainer.setLayoutParams(lp);
+ // 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);
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index d05673c..596aa8f 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -29,6 +29,7 @@
public class ExtendedEditText extends EditText {
private boolean mShowImeAfterFirstLayout;
+ private boolean mForceDisableSuggestions = false;
/**
* Implemented by listeners of the back key.
@@ -107,4 +108,17 @@
mBackKeyListener.onBackKey();
}
}
+
+ /**
+ * Set to true when you want isSuggestionsEnabled to return false.
+ * Use this to disable the red underlines that appear under typos when suggestions is enabled.
+ */
+ public void forceDisableSuggestions(boolean forceDisableSuggestions) {
+ mForceDisableSuggestions = forceDisableSuggestions;
+ }
+
+ @Override
+ public boolean isSuggestionsEnabled() {
+ return !mForceDisableSuggestions && super.isSuggestionsEnabled();
+ }
}
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index be3ba90..5a44f75 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -167,7 +167,7 @@
}
}
- public IconPalette getIconPalette() {
+ protected IconPalette getIconPalette() {
if (mIconPalette == null) {
mIconPalette = IconPalette.fromDominantColor(Utilities
.findDominantColorByHue(mBitmap, 20));
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index ffddccf..0041bb4 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -114,9 +114,9 @@
}
}
- public void prepareAutoAdd() {
+ public void prepareAutoUpdate() {
for (int i = 0; i < listeners.size(); i++) {
- listeners.get(i).prepareAutoAdd();
+ listeners.get(i).prepareAutoUpdate();
}
}
@@ -125,7 +125,7 @@
public void onRemove(ShortcutInfo item);
public void onTitleChanged(CharSequence title);
public void onItemsChanged(boolean animate);
- public void prepareAutoAdd();
+ public void prepareAutoUpdate();
}
public boolean hasOption(int optionFlag) {
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 1bab774..ce85570 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -218,6 +218,10 @@
queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, widgetId, context), context);
}
+ public static void queueActivityInfo(LauncherActivityInfo activity, Context context) {
+ queuePendingShortcutInfo(new PendingInstallShortcutInfo(activity, context), context);
+ }
+
public static HashSet<ShortcutKey> getPendingShortcuts(Context context) {
HashSet<ShortcutKey> result = new HashSet<>();
@@ -324,7 +328,7 @@
user = info.getUser();
mContext = context;
- launchIntent = AppInfo.makeLaunchIntent(context, info, user);
+ launchIntent = AppInfo.makeLaunchIntent(info);
label = info.getLabel().toString();
}
@@ -340,7 +344,7 @@
mContext = context;
user = info.getUserHandle();
- launchIntent = info.makeIntent(context);
+ launchIntent = info.makeIntent();
label = info.getShortLabel().toString();
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 8aeab87..9e214d1 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -29,7 +29,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.ProviderConfig;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.util.Thunk;
import org.xmlpull.v1.XmlPullParser;
@@ -90,8 +89,8 @@
public float hotseatScale;
int defaultLayoutId;
- DeviceProfile landscapeProfile;
- DeviceProfile portraitProfile;
+ public DeviceProfile landscapeProfile;
+ public DeviceProfile portraitProfile;
public Point defaultWallpaperSize;
@@ -188,23 +187,6 @@
}
}
- public void dumpDisplayInfo(Context context) {
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- Display display = wm.getDefaultDisplay();
- DisplayMetrics dm = new DisplayMetrics();
- display.getMetrics(dm);
-
- Point smallestSize = new Point();
- Point largestSize = new Point();
- display.getCurrentSizeRange(smallestSize, largestSize);
-
- FileLog.e("DisplayInfo", "Default Density: " + DisplayMetrics.DENSITY_DEFAULT);
- FileLog.e("DisplayInfo", "Density: " + dm.densityDpi);
- FileLog.e("DisplayInfo", "Smallest size: " + smallestSize);
- FileLog.e("DisplayInfo", "Largest size: " + largestSize);
- FileLog.e("DisplayInfo", "minWidth/Height DPS: " + minWidthDps + ", " + minHeightDps);
- }
-
ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles(Context context) {
ArrayList<InvariantDeviceProfile> profiles = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index aec6c7d..0779a3d 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -29,11 +29,6 @@
*/
public class ItemInfo {
- /**
- * Intent extra to store the profile. Format: UserHandle
- */
- public static final String EXTRA_PROFILE = "profile";
-
public static final int NO_ID = -1;
/**
diff --git a/src/com/android/launcher3/ItemInfoWithIcon.java b/src/com/android/launcher3/ItemInfoWithIcon.java
index a3d8c6a..1e020e2 100644
--- a/src/com/android/launcher3/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/ItemInfoWithIcon.java
@@ -35,7 +35,9 @@
protected ItemInfoWithIcon() { }
- protected ItemInfoWithIcon(ItemInfo info) {
+ protected ItemInfoWithIcon(ItemInfoWithIcon info) {
super(info);
+ iconBitmap = info.iconBitmap;
+ usingLowResIcon = info.usingLowResIcon;
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8ab3920..6fbe542 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -71,6 +71,7 @@
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.OvershootInterpolator;
@@ -85,9 +86,6 @@
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DefaultAppSearchController;
import com.android.launcher3.anim.AnimationLayerSet;
-import com.android.launcher3.model.ModelWriter;
-import com.android.launcher3.notification.NotificationListener;
-import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PinItemRequestCompat;
@@ -106,10 +104,13 @@
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.popup.PopupContainerWithArrow;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -119,7 +120,6 @@
import com.android.launcher3.util.ActivityResultInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LogConfig;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
@@ -175,6 +175,11 @@
*/
protected static final int REQUEST_LAST = 100;
+ private static final int SOFT_INPUT_MODE_DEFAULT =
+ WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
+ private static final int SOFT_INPUT_MODE_ALL_APPS =
+ WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+
// The Intent extra that defines whether to ignore the launch animation
static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
"com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";
@@ -315,8 +320,6 @@
*/
private PendingRequestArgs mPendingRequestArgs;
- private UserEventDispatcher mUserEventDispatcher;
-
private float mLastDispatchTouchEventX = 0.0f;
public ViewGroupFocusHelper mFocusHandler;
@@ -480,7 +483,7 @@
// It's possible that All Apps is visible when this is run,
// so always use light status bar in that case. Only change nav bar color to status bar
// color when All Apps is visible.
- activateLightStatusBar(lightStatusBar || isAllAppsVisible(), isAllAppsVisible());
+ activateLightSystemBars(lightStatusBar || isAllAppsVisible(), true, isAllAppsVisible());
}
}
@@ -488,21 +491,26 @@
private static final int SYSTEM_UI_FLAG_LIGHT_NAV_BAR = 0x10;
/**
- * Sets the status bar to be light or not. Light status bar means dark icons.
- * @param lightStatusBar make sure the status bar is light
- * @param changeNavBar if true, make the nav bar theme in sync with status bar.
+ * Sets the status and/or nav bar to be light or not. Light status bar means dark icons.
+ * @param isLight make sure the system bar is light.
+ * @param statusBar if true, make the status bar theme match the isLight param.
+ * @param navBar if true, make the nav bar theme match the isLight param.
*/
- public void activateLightStatusBar(boolean lightStatusBar, boolean changeNavBar) {
+ public void activateLightSystemBars(boolean isLight, boolean statusBar, boolean navBar) {
int oldSystemUiFlags = getWindow().getDecorView().getSystemUiVisibility();
int newSystemUiFlags = oldSystemUiFlags;
- if (lightStatusBar) {
- newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ;
- if (changeNavBar && Utilities.isAtLeastO()) {
+ if (isLight) {
+ if (statusBar) {
+ newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+ }
+ if (navBar && Utilities.isAtLeastO()) {
newSystemUiFlags |= SYSTEM_UI_FLAG_LIGHT_NAV_BAR;
}
} else {
- newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
- if (changeNavBar && Utilities.isAtLeastO()) {
+ if (statusBar) {
+ newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ }
+ if (navBar && Utilities.isAtLeastO()) {
newSystemUiFlags &= ~(SYSTEM_UI_FLAG_LIGHT_NAV_BAR);
}
}
@@ -627,23 +635,6 @@
}
}
- public UserEventDispatcher getUserEventDispatcher() {
- if (mLauncherCallbacks != null) {
- UserEventDispatcher dispatcher = mLauncherCallbacks.getUserEventDispatcher();
- if (dispatcher != null) {
- return dispatcher;
- }
- }
-
- // Logger object is a singleton and does not have to be coupled with the foreground
- // activity. Since most user event logging is done on the UI, the object is retrieved
- // from the callback for convenience.
- if (mUserEventDispatcher == null) {
- mUserEventDispatcher = new UserEventDispatcher();
- }
- return mUserEventDispatcher;
- }
-
public boolean isDraggingEnabled() {
// We prevent dragging when we are loading the workspace as it is possible to pick up a view
// that is subsequently removed from the workspace in startBinding().
@@ -1071,6 +1062,7 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onResume();
}
+
}
@Override
@@ -1163,9 +1155,10 @@
if (mLauncherCallbacks != null) {
return mLauncherCallbacks.hasSettings();
} else {
- // On devices with a locked orientation, we will at least have the allow rotation
- // setting.
- return !getResources().getBoolean(R.bool.allow_rotation);
+ // On O and above we there is always some setting present settings (add icon to
+ // home screen or icon badging). On earlier APIs we will have the allow rotation
+ // setting, on devices with a locked orientation,
+ return Utilities.isAtLeastO() || !getResources().getBoolean(R.bool.allow_rotation);
}
}
@@ -1463,9 +1456,14 @@
}
if (info == null) {
- info = InstallShortcutReceiver.fromShortcutIntent(this, data);
+ // Legacy shortcuts are only supported for primary profile.
+ info = Process.myUserHandle().equals(args.user)
+ ? InstallShortcutReceiver.fromShortcutIntent(this, data) : null;
- if (info == null || !new PackageManagerHelper(this).hasPermissionForActivity(
+ if (info == null) {
+ Log.e(TAG, "Unable to parse a valid custom shortcut result");
+ return;
+ } else if (!new PackageManagerHelper(this).hasPermissionForActivity(
info.intent, args.getPendingIntent().getComponent().getPackageName())) {
// The app is trying to add a shortcut without sufficient permissions
Log.e(TAG, "Ignoring malicious intent " + info.intent.toUri(0));
@@ -2474,7 +2472,7 @@
throw new IllegalArgumentException("Input must have a valid intent");
}
boolean success = startActivitySafely(v, intent, item);
- getUserEventDispatcher().logAppLaunch(v, intent);
+ getUserEventDispatcher().logAppLaunch(v, intent); // TODO for discovered apps b/35802115
if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
@@ -2711,11 +2709,7 @@
!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
Bundle optsBundle = useLaunchAnimation ? getActivityLaunchOptions(v) : null;
- UserHandle user = null;
- if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {
- long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);
- user = UserManagerCompat.getInstance(this).getUserForSerialNumber(serialNumber);
- }
+ UserHandle user = item == null ? null : item.user;
// Prepare intent
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -2723,9 +2717,10 @@
intent.setSourceBounds(getViewBounds(v));
}
try {
- if (Utilities.ATLEAST_MARSHMALLOW && item != null
+ if (Utilities.ATLEAST_MARSHMALLOW
+ && (item instanceof ShortcutInfo)
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
- || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
+ || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((ShortcutInfo) item).isPromise()) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
@@ -2898,7 +2893,7 @@
}
// Change the state *after* we've called all the transition code
- mState = State.WORKSPACE;
+ setState(State.WORKSPACE);
if (changed) {
// Send an accessibility event to announce the context change
@@ -2935,12 +2930,30 @@
mWorkspace.setVisibility(View.VISIBLE);
mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(),
Workspace.State.OVERVIEW, animated, postAnimRunnable);
- mState = State.WORKSPACE;
+ setState(State.WORKSPACE);
+
// If animated from long press, then don't allow any of the controller in the drag
// layer to intercept any remaining touch.
mWorkspace.requestDisallowInterceptTouchEvent(animated);
}
+ private void setState(State state) {
+ this.mState = state;
+ updateSoftInputMode();
+ }
+
+ private void updateSoftInputMode() {
+ if (FeatureFlags.LAUNCHER3_UPDATE_SOFT_INPUT_MODE) {
+ final int mode;
+ if (isAppsViewVisible()) {
+ mode = SOFT_INPUT_MODE_ALL_APPS;
+ } else {
+ mode = SOFT_INPUT_MODE_DEFAULT;
+ }
+ getWindow().setSoftInputMode(mode);
+ }
+ }
+
/**
* Shows the apps view.
*/
@@ -3002,7 +3015,7 @@
}
// Change the state *after* we've called all the transition code
- mState = toState;
+ setState(toState);
AbstractFloatingView.closeAllOpenViews(this);
// Send an accessibility event to announce the context change
@@ -3032,7 +3045,7 @@
mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(),
Workspace.State.SPRING_LOADED, true /* animated */,
null /* onCompleteRunnable */);
- mState = State.WORKSPACE_SPRING_LOADED;
+ setState(State.WORKSPACE_SPRING_LOADED);
}
public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 43cf827..aa7f5ee 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -130,17 +130,4 @@
return anim;
}
- public static ValueAnimator animateViewHeight(final View v, int fromHeight, int toHeight) {
- ValueAnimator anim = ValueAnimator.ofInt(fromHeight, toHeight);
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- int val = (Integer) valueAnimator.getAnimatedValue();
- ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
- layoutParams.height = val;
- v.setLayoutParams(layoutParams);
- }
- });
- return anim;
- }
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 2e75579..180c202 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -28,7 +28,6 @@
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dynamicui.ExtractionUtils;
-import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.TestingUtils;
@@ -54,8 +53,6 @@
if (INSTANCE == null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
INSTANCE = new LauncherAppState(context.getApplicationContext());
- GridSizeMigrationTask.logDeviceProfileIfChanged(
- INSTANCE.getInvariantDeviceProfile(), context);
} else {
try {
return new MainThreadExecutor().submit(new Callable<LauncherAppState>() {
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
index 6394b90..2bac11f 100644
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -92,7 +92,6 @@
/*
* Extensions points for adding / replacing some other aspects of the Launcher experience.
*/
- public UserEventDispatcher getUserEventDispatcher();
public boolean shouldMoveToDefaultScreenOnHomeIntent();
public boolean hasSettings();
public AllAppsSearchBarController getAllAppsSearchBarController();
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 8c90c2c..5a41eeb 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -981,7 +981,7 @@
c.markDeleted("Unrestored app removed: " + targetPkg);
continue;
}
- } else if (pmHelper.isAppOnSdcard(targetPkg)) {
+ } 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.
@@ -1032,8 +1032,7 @@
info.iconBitmap = LauncherIcons
.createShortcutIcon(pinnedShortcut, context);
if (pmHelper.isAppSuspended(
- info.getTargetComponent().getPackageName(),
- info.user)) {
+ pinnedShortcut.getPackage(), info.user)) {
info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
}
intent = info.intent;
@@ -1046,7 +1045,7 @@
info = c.loadSimpleShortcut();
// Shortcuts are only available on the primary profile
- if (pmHelper.isAppSuspended(targetPkg)) {
+ if (pmHelper.isAppSuspended(targetPkg, c.user)) {
disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
}
@@ -1070,9 +1069,6 @@
info.rank = c.getInt(rankIndex);
info.spanX = 1;
info.spanY = 1;
- // TODO: Remove this extra. Instead we should be using
- // itemInfo#user.
- info.intent.putExtra(ItemInfo.EXTRA_PROFILE, c.serialNumber);
info.isDisabled |= disabledState;
if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
@@ -1686,7 +1682,7 @@
for (int i = 0; i < apps.size(); i++) {
LauncherActivityInfo app = apps.get(i);
// This builds the icon bitmaps.
- mBgAllAppsList.add(new AppInfo(mContext, app, user, quietMode), app);
+ mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
}
final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user);
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index e250b3f..a750406 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -72,7 +72,7 @@
private static final String TAG = "LauncherProvider";
private static final boolean LOGD = false;
- private static final int DATABASE_VERSION = 27;
+ private static final int DATABASE_VERSION = 28;
public static final String AUTHORITY = ProviderConfig.AUTHORITY;
@@ -791,6 +791,26 @@
break;
}
case 27: {
+ // Remove "profile extra"
+ db.beginTransaction();
+ try {
+ UserManagerCompat um = UserManagerCompat.getInstance(mContext);
+ for (UserHandle user : um.getUserProfiles()) {
+ long serial = um.getSerialNumberForUser(user);
+ String sql = "update favorites set intent = replace(intent, "
+ + "';l.profile=" + serial + ";', ';') where itemType = 0;";
+ db.execSQL(sql);
+ }
+ db.setTransactionSuccessful();
+ } catch (SQLException ex) {
+ Log.e(TAG, ex.getMessage(), ex);
+ // Old version remains, which means we wipe old data
+ break;
+ } finally {
+ db.endTransaction();
+ }
+ }
+ case 28: {
// DB Upgraded successfully
return;
}
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index 43fa4aa..b163464 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -73,7 +73,7 @@
mPaint.setColor(Themes.getAttrColor(getContext(), android.R.attr.textColorPrimary));
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
mLauncher.getDeviceProfile().iconTextSizePx, getResources().getDisplayMetrics()));
- setBackgroundResource(R.drawable.round_rect_primary);
+ setBackgroundResource(R.drawable.pending_widget_bg);
setWillNotDraw(false);
setElevation(getResources().getDimension(R.dimen.pending_widget_elevation));
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
new file mode 100644
index 0000000..203bc25
--- /dev/null
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Process;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+
+import java.util.List;
+
+/**
+ * BroadcastReceiver to handle session commit intent.
+ */
+public class SessionCommitReceiver extends BroadcastReceiver {
+
+ private static final long SESSION_IGNORE_DURATION = 3 * 60 * 60 * 1000; // 3 hours
+
+ // Preference key for automatically adding icon to homescreen.
+ public static final String ADD_ICON_PREFERENCE_KEY = "pref_add_icon_to_home";
+
+ private static final String KEY_FIRST_TIME = "first_session_broadcast_time";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!isEnabled(context)) {
+ // User has decided to not add icons on homescreen.
+ return;
+ }
+
+ SessionInfo info = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
+ UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
+ // TODO: Verify install reason
+ if (TextUtils.isEmpty(info.getAppPackageName())) {
+ return;
+ }
+
+ if (!Process.myUserHandle().equals(user)) {
+ // Managed profile is handled using ManagedProfileHeuristic
+ return;
+ }
+
+ // STOPSHIP: Remove this workaround when we start getting proper install reason
+ SharedPreferences prefs = context
+ .getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0);
+ long now = System.currentTimeMillis();
+ long firstTime = prefs.getLong(KEY_FIRST_TIME, now);
+ prefs.edit().putLong(KEY_FIRST_TIME, firstTime).apply();
+ if ((now - firstTime) < SESSION_IGNORE_DURATION) {
+ Log.d("SessionCommitReceiver", "Temporarily ignoring session broadcast");
+ return;
+ }
+
+ List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
+ .getActivityList(info.getAppPackageName(), user);
+ if (activities == null || activities.isEmpty()) {
+ // no activity found
+ return;
+ }
+ InstallShortcutReceiver.queueActivityInfo(activities.get(0), context);
+ }
+
+ public static boolean isEnabled(Context context) {
+ return Utilities.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true);
+ }
+}
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index cedeb39..552e24a 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -25,6 +25,7 @@
import android.preference.PreferenceFragment;
import android.provider.Settings;
import android.provider.Settings.System;
+import android.support.v4.os.BuildCompat;
/**
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
@@ -72,6 +73,11 @@
mRotationLockObserver.onChange(true);
rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
}
+
+ if (!BuildCompat.isAtLeastO()) {
+ getPreferenceScreen().removePreference(
+ findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
+ }
}
@Override
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index b35dcb7..6f0417c 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -134,7 +134,6 @@
title = info.title;
intent = new Intent(info.intent);
iconResource = info.iconResource;
- iconBitmap = info.iconBitmap;
status = info.status;
mInstallProgress = info.mInstallProgress;
isDisabled = info.isDisabled;
@@ -146,8 +145,6 @@
title = Utilities.trim(info.title);
intent = new Intent(info.intent);
isDisabled = info.isDisabled;
- iconBitmap = info.iconBitmap;
- usingLowResIcon = info.usingLowResIcon;
}
/**
@@ -202,7 +199,7 @@
public void updateFromDeepShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
// {@link ShortcutInfoCompat#getActivity} can change during an update. Recreate the intent
- intent = shortcutInfo.makeIntent(context);
+ intent = shortcutInfo.makeIntent();
title = shortcutInfo.getShortLabel();
CharSequence label = shortcutInfo.getLongLabel();
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index e68a5b0..0fac29f 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -5,6 +5,7 @@
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
@@ -139,9 +140,10 @@
final Runnable checkIfUninstallWasSuccess = new Runnable() {
@Override
public void run() {
- String packageName = cn.getPackageName();
- boolean uninstallSuccessful = !AllAppsList.packageHasActivities(
- launcher, packageName, user);
+ // We use MATCH_UNINSTALLED_PACKAGES as the app can be on SD card as well.
+ boolean uninstallSuccessful = LauncherAppsCompat.getInstance(launcher)
+ .getApplicationInfo(cn.getPackageName(),
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, user) == null;
callback.onDragObjectRemoved(uninstallSuccessful);
}
};
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index abc5367..207a7d4 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -468,13 +468,8 @@
&& TextUtils.isEmpty(launchIntent.getDataString())) {
// An app target can either have no extra or have ItemInfo.EXTRA_PROFILE.
Bundle extras = launchIntent.getExtras();
- if (extras == null) {
- return true;
- } else {
- Set<String> keys = extras.keySet();
- return keys.size() == 1 && keys.contains(ItemInfo.EXTRA_PROFILE);
- }
- };
+ return extras == null || extras.keySet().isEmpty();
+ }
return false;
}
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 689cc9b..0e91062 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -22,6 +22,7 @@
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.UserHandle;
import android.support.v4.graphics.ColorUtils;
@@ -89,14 +90,17 @@
*
* @return a request id which can be used to cancel the request.
*/
- public PreviewLoadRequest getPreview(WidgetItem item, int previewWidth,
+ public CancellationSignal getPreview(WidgetItem item, int previewWidth,
int previewHeight, WidgetCell caller) {
String size = previewWidth + "x" + previewHeight;
WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size);
PreviewLoadTask task = new PreviewLoadTask(key, item, previewWidth, previewHeight, caller);
task.executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
- return new PreviewLoadRequest(task);
+
+ CancellationSignal signal = new CancellationSignal();
+ signal.setOnCancelListener(task);
+ return signal;
}
/**
@@ -510,42 +514,8 @@
}
}
- /**
- * A request Id which can be used by the client to cancel any request.
- */
- public class PreviewLoadRequest {
-
- @Thunk final PreviewLoadTask mTask;
-
- public PreviewLoadRequest(PreviewLoadTask task) {
- mTask = task;
- }
-
- public void cleanup() {
- if (mTask != null) {
- mTask.cancel(true);
- }
-
- // This only handles the case where the PreviewLoadTask is cancelled after the task has
- // successfully completed (including having written to disk when necessary). In the
- // other cases where it is cancelled while the task is running, it will be cleaned up
- // in the tasks's onCancelled() call, and if cancelled while the task is writing to
- // disk, it will be cancelled in the task's onPostExecute() call.
- if (mTask.mBitmapToRecycle != null) {
- mWorkerHandler.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mUnusedBitmaps) {
- mUnusedBitmaps.add(mTask.mBitmapToRecycle);
- }
- mTask.mBitmapToRecycle = null;
- }
- });
- }
- }
- }
-
- public class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap> {
+ public class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap>
+ implements CancellationSignal.OnCancelListener {
@Thunk final WidgetCacheKey mKey;
private final WidgetItem mInfo;
private final int mPreviewHeight;
@@ -661,6 +631,28 @@
});
}
}
+
+ @Override
+ public void onCancel() {
+ cancel(true);
+
+ // This only handles the case where the PreviewLoadTask is cancelled after the task has
+ // successfully completed (including having written to disk when necessary). In the
+ // other cases where it is cancelled while the task is running, it will be cleaned up
+ // in the tasks's onCancelled() call, and if cancelled while the task is writing to
+ // disk, it will be cancelled in the task's onPostExecute() call.
+ if (mBitmapToRecycle != null) {
+ mWorkerHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mUnusedBitmaps) {
+ mUnusedBitmaps.add(mBitmapToRecycle);
+ }
+ mBitmapToRecycle = null;
+ }
+ });
+ }
+ }
}
private static final class WidgetCacheKey extends ComponentKey {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 56aa69e..7562dd8 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -643,7 +643,8 @@
// 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.
- if (getChildCount() > 0) {
+ // 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();
@@ -3885,7 +3886,9 @@
// The item may belong to a folder.
View parent = idToViewMap.get(itemToRemove.container);
if (parent != null) {
- ((FolderInfo) parent.getTag()).remove((ShortcutInfo) itemToRemove, false);
+ FolderInfo folderInfo = (FolderInfo) parent.getTag();
+ folderInfo.prepareAutoUpdate();
+ folderInfo.remove((ShortcutInfo) itemToRemove, false);
}
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 0732004..cc5fa8c 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -20,6 +20,8 @@
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.InsetDrawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.text.Selection;
import android.text.Spannable;
@@ -46,6 +48,8 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.discovery.AppDiscoveryItem;
+import com.android.launcher3.discovery.AppDiscoveryUpdateState;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.folder.Folder;
@@ -211,7 +215,7 @@
// IF scroller is at the very top OR there is no scroll bar because there is probably not
// enough items to scroll, THEN it's okay for the container to be pulled down.
- if (mAppsRecyclerView.getScrollBar().getThumbOffsetY() <= 0) {
+ if (mAppsRecyclerView.getCurrentScrollY() == 0) {
return true;
}
return false;
@@ -425,14 +429,22 @@
@Override
public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
if (apps != null) {
- if (mApps.setOrderedFilter(apps)) {
- mAppsRecyclerView.onSearchResultsChanged();
- }
+ mApps.setOrderedFilter(apps);
+ mAppsRecyclerView.onSearchResultsChanged();
mAdapter.setLastSearchQuery(query);
}
}
@Override
+ public void onAppDiscoverySearchUpdate(@Nullable AppDiscoveryItem app,
+ @NonNull AppDiscoveryUpdateState state) {
+ if (!mLauncher.isDestroyed()) {
+ mApps.onAppDiscoverySearchUpdate(app, state);
+ mAppsRecyclerView.onSearchResultsChanged();
+ }
+ }
+
+ @Override
public void clearSearchResult() {
if (mApps.setOrderedFilter(null)) {
mAppsRecyclerView.onSearchResultsChanged();
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index f352304..59cac8d 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -33,12 +33,13 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
+import com.android.launcher3.discovery.AppDiscoveryAppInfo;
import com.android.launcher3.AppInfo;
import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
+import com.android.launcher3.discovery.AppDiscoveryItemView;
import java.util.List;
@@ -67,6 +68,8 @@
public static final int VIEW_TYPE_SEARCH_DIVIDER = 1 << 6;
// The divider that separates prediction icons from the app list
public static final int VIEW_TYPE_PREDICTION_DIVIDER = 1 << 7;
+ public static final int VIEW_TYPE_APPS_LOADING_DIVIDER = 1 << 8;
+ public static final int VIEW_TYPE_DISCOVERY_ITEM = 1 << 9;
// Common view type masks
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_SEARCH_DIVIDER
@@ -74,6 +77,8 @@
| VIEW_TYPE_PREDICTION_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON
| VIEW_TYPE_PREDICTION_ICON;
+ public static final int VIEW_TYPE_MASK_CONTENT = VIEW_TYPE_MASK_ICON
+ | VIEW_TYPE_DISCOVERY_ITEM;
public interface BindViewCallback {
@@ -84,7 +89,6 @@
* ViewHolder for each icon.
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
-
public ViewHolder(View v) {
super(v);
}
@@ -150,7 +154,7 @@
adapterPosition = Math.max(adapterPosition, mApps.getAdapterItems().size() - 1);
int extraRows = 0;
for (int i = 0; i <= adapterPosition; i++) {
- if ((items.get(i).viewType & VIEW_TYPE_MASK_ICON) == 0) {
+ if (!isViewType(items.get(i).viewType, VIEW_TYPE_MASK_CONTENT)) {
extraRows++;
}
}
@@ -273,8 +277,7 @@
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_ICON:
- /* falls through */
- case VIEW_TYPE_PREDICTION_ICON: {
+ case VIEW_TYPE_PREDICTION_ICON:
BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
R.layout.all_apps_icon, parent, false);
icon.setOnClickListener(mIconClickListener);
@@ -284,14 +287,14 @@
icon.setOnFocusChangeListener(mIconFocusListener);
// Ensure the all apps icon height matches the workspace icons
- DeviceProfile profile = mLauncher.getDeviceProfile();
- Point cellSize = profile.getCellSize();
- GridLayoutManager.LayoutParams lp =
- (GridLayoutManager.LayoutParams) icon.getLayoutParams();
- lp.height = cellSize.y;
- icon.setLayoutParams(lp);
+ icon.getLayoutParams().height = getCellSize().y;
return new ViewHolder(icon);
- }
+ case VIEW_TYPE_DISCOVERY_ITEM:
+ AppDiscoveryItemView appDiscoveryItemView = (AppDiscoveryItemView) mLayoutInflater
+ .inflate(R.layout.all_apps_discovery_item, parent, false);
+ appDiscoveryItemView.init(mIconClickListener, mLauncher.getAccessibilityDelegate(),
+ mIconLongClickListener);
+ return new ViewHolder(appDiscoveryItemView);
case VIEW_TYPE_EMPTY_SEARCH:
return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search,
parent, false));
@@ -308,8 +311,11 @@
case VIEW_TYPE_SEARCH_DIVIDER:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.all_apps_search_divider, parent, false));
+ case VIEW_TYPE_APPS_LOADING_DIVIDER:
+ View loadingDividerView = mLayoutInflater.inflate(
+ R.layout.all_apps_discovery_loading_divider, parent, false);
+ return new ViewHolder(loadingDividerView);
case VIEW_TYPE_PREDICTION_DIVIDER:
- /* falls through */
case VIEW_TYPE_SEARCH_MARKET_DIVIDER:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.all_apps_divider, parent, false));
@@ -318,23 +324,26 @@
}
}
+ private Point getCellSize() {
+ return mLauncher.getDeviceProfile().getCellSize();
+ }
+
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
- case VIEW_TYPE_ICON: {
+ case VIEW_TYPE_ICON:
+ case VIEW_TYPE_PREDICTION_ICON:
AppInfo info = mApps.getAdapterItems().get(position).appInfo;
BubbleTextView icon = (BubbleTextView) holder.itemView;
icon.applyFromApplicationInfo(info);
icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
break;
- }
- case VIEW_TYPE_PREDICTION_ICON: {
- AppInfo info = mApps.getAdapterItems().get(position).appInfo;
- BubbleTextView icon = (BubbleTextView) holder.itemView;
- icon.applyFromApplicationInfo(info);
- icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
+ case VIEW_TYPE_DISCOVERY_ITEM:
+ AppDiscoveryAppInfo appDiscoveryAppInfo = (AppDiscoveryAppInfo)
+ mApps.getAdapterItems().get(position).appInfo;
+ AppDiscoveryItemView view = (AppDiscoveryItemView) holder.itemView;
+ view.apply(appDiscoveryAppInfo);
break;
- }
case VIEW_TYPE_EMPTY_SEARCH:
TextView emptyViewText = (TextView) holder.itemView;
emptyViewText.setText(mEmptySearchMessage);
@@ -349,6 +358,15 @@
searchView.setVisibility(View.GONE);
}
break;
+ case VIEW_TYPE_APPS_LOADING_DIVIDER:
+ int visLoading = mApps.isAppDiscoveryRunning() ? View.VISIBLE : View.GONE;
+ int visLoaded = !mApps.isAppDiscoveryRunning() ? View.VISIBLE : View.GONE;
+ holder.itemView.findViewById(R.id.loadingProgressBar).setVisibility(visLoading);
+ holder.itemView.findViewById(R.id.loadedDivider).setVisibility(visLoaded);
+ break;
+ case VIEW_TYPE_SEARCH_MARKET_DIVIDER:
+ // nothing to do
+ break;
}
if (mBindViewCallback != null) {
mBindViewCallback.onBindView(holder);
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index a41d832..64e2fcb 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -30,6 +30,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -110,44 +111,40 @@
* all the different view types.
*/
public void preMeasureViews(AllAppsGridAdapter adapter) {
+ View icon = adapter.onCreateViewHolder(this, AllAppsGridAdapter.VIEW_TYPE_ICON).itemView;
+ final int iconHeight = icon.getLayoutParams().height;
+ mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, iconHeight);
+ mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_ICON, iconHeight);
+
final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
getResources().getDisplayMetrics().widthPixels, View.MeasureSpec.AT_MOST);
final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
getResources().getDisplayMetrics().heightPixels, View.MeasureSpec.AT_MOST);
- // Icons
- BubbleTextView icon = (BubbleTextView) adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_ICON).itemView;
- int iconHeight = icon.getLayoutParams().height;
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, iconHeight);
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_ICON, iconHeight);
+ putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
+ AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER,
+ AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER);
+ putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
+ AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER);
+ putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
+ AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET);
+ putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
+ AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH);
- // Search divider
- View searchDivider = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER).itemView;
- searchDivider.measure(widthMeasureSpec, heightMeasureSpec);
- int searchDividerHeight = searchDivider.getMeasuredHeight();
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER, searchDividerHeight);
+ if (FeatureFlags.DISCOVERY_ENABLED) {
+ putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
+ AllAppsGridAdapter.VIEW_TYPE_APPS_LOADING_DIVIDER);
+ putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
+ AllAppsGridAdapter.VIEW_TYPE_DISCOVERY_ITEM);
+ }
+ }
- // Generic dividers
- View divider = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER).itemView;
- divider.measure(widthMeasureSpec, heightMeasureSpec);
- int dividerHeight = divider.getMeasuredHeight();
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER, dividerHeight);
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER, dividerHeight);
-
- // Search views
- View emptySearch = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH).itemView;
- emptySearch.measure(widthMeasureSpec, heightMeasureSpec);
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH,
- emptySearch.getMeasuredHeight());
- View searchMarket = adapter.onCreateViewHolder(this,
- AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET).itemView;
- searchMarket.measure(widthMeasureSpec, heightMeasureSpec);
- mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET,
- searchMarket.getMeasuredHeight());
+ private void putSameHeightFor(AllAppsGridAdapter adapter, int w, int h, int... viewTypes) {
+ View view = adapter.onCreateViewHolder(this, viewTypes[0]).itemView;
+ view.measure(w, h);
+ for (int viewType : viewTypes) {
+ mViewHeights.put(viewType, view.getMeasuredHeight());
+ }
}
/**
@@ -207,7 +204,7 @@
// Always scroll the view to the top so the user can see the changed results
scrollToTop();
- if (mApps.hasNoFilteredResults()) {
+ if (mApps.shouldShowEmptySearch()) {
if (mEmptySearchBackground == null) {
mEmptySearchBackground = DrawableFactory.get(getContext())
.getAllAppsBackground(getContext());
@@ -438,4 +435,5 @@
x + mEmptySearchBackground.getIntrinsicWidth(),
y + mEmptySearchBackground.getIntrinsicHeight());
}
+
}
diff --git a/src/com/android/launcher3/allapps/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/AllAppsSearchBarController.java
index 365ab31..c7ba3ab 100644
--- a/src/com/android/launcher3/allapps/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/AllAppsSearchBarController.java
@@ -19,6 +19,8 @@
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@@ -32,6 +34,8 @@
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
+import com.android.launcher3.discovery.AppDiscoveryItem;
+import com.android.launcher3.discovery.AppDiscoveryUpdateState;
import com.android.launcher3.util.ComponentKey;
import java.util.ArrayList;
@@ -46,7 +50,7 @@
protected AlphabeticalAppsList mApps;
protected Callbacks mCb;
protected ExtendedEditText mInput;
- private String mQuery;
+ protected String mQuery;
protected DefaultAppSearchAlgorithm mSearchAlgorithm;
protected InputMethodManager mInputMethodManager;
@@ -73,6 +77,14 @@
mInput.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
mSearchAlgorithm = onInitializeSearch();
+
+ onInitialized();
+ }
+
+ /**
+ * You can override this method to perform custom initialization.
+ */
+ protected void onInitialized() {
}
/**
@@ -117,6 +129,7 @@
if (actionId != EditorInfo.IME_ACTION_SEARCH) {
return false;
}
+
// Skip if the query is empty
String query = v.getText().toString();
if (query.isEmpty()) {
@@ -206,5 +219,19 @@
* Called when the search results should be cleared.
*/
void clearSearchResult();
+
+
+ /**
+ * Called when the app discovery is providing an update of search, which can either be
+ * START for starting a new discovery,
+ * UPDATE for providing a new search result, can be called multiple times,
+ * END for indicating the end of results.
+ *
+ * @param app result item if UPDATE, else null
+ * @param app the update state, START, UPDATE or END
+ */
+ void onAppDiscoverySearchUpdate(@Nullable AppDiscoveryItem app,
+ @NonNull AppDiscoveryUpdateState state);
}
+
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index b436fa2..30ed180 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -9,7 +9,6 @@
import android.graphics.Color;
import android.support.v4.graphics.ColorUtils;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
@@ -47,11 +46,10 @@
private final Interpolator mAccelInterpolator = new AccelerateInterpolator(2f);
private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f);
private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator();
- private final ScrollInterpolator mScrollInterpolator = new ScrollInterpolator();
+ private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator
+ = new VerticalPullDetector.ScrollInterpolator();
- private static final float ANIMATION_DURATION = 1200;
private static final float PARALLAX_COEFFICIENT = .125f;
- private static final float FAST_FLING_PX_MS = 10;
private static final int SINGLE_FRAME_MS = 16;
private AllAppsContainerView mAppsView;
@@ -262,7 +260,7 @@
// Use a light status bar (dark icons) if all apps is behind at least half of the status
// bar. If the status bar is already light due to wallpaper extraction, keep it that way.
boolean forceLight = shift <= mStatusBarHeight / 2;
- mLauncher.activateLightStatusBar(forceLight, true);
+ mLauncher.activateLightSystemBars(forceLight, true /* statusBar */, true /* navBar */);
}
/**
@@ -315,13 +313,7 @@
}
private void calculateDuration(float velocity, float disp) {
- // TODO: make these values constants after tuning.
- float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity));
- float travelDistance = Math.max(0.2f, disp / mShiftRange);
- mAnimationDuration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance);
- if (DBG) {
- Log.d(TAG, String.format("calculateDuration=%d, v=%f, d=%f", mAnimationDuration, velocity, disp));
- }
+ mAnimationDuration = mDetector.calculateDuration(velocity, disp / mShiftRange);
}
public boolean animateToAllApps(AnimatorSet animationOut, long duration) {
@@ -511,21 +503,4 @@
setProgress(mProgress);
}
- static class ScrollInterpolator implements Interpolator {
-
- boolean mSteeper;
-
- public void setVelocityAtZero(float velocity) {
- mSteeper = velocity > FAST_FLING_PX_MS;
- }
-
- public float getInterpolation(float t) {
- t -= 1.0f;
- float output = t * t * t;
- if (mSteeper) {
- output *= t * t; // Make interpolation initial slope steeper
- }
- return output + 1;
- }
- }
}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 0bfbd3e..f5cf7ef 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -17,12 +17,17 @@
import android.content.Context;
import android.os.Process;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.Log;
import com.android.launcher3.AppInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.discovery.AppDiscoveryAppInfo;
+import com.android.launcher3.discovery.AppDiscoveryItem;
+import com.android.launcher3.discovery.AppDiscoveryUpdateState;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LabelComparator;
@@ -48,6 +53,8 @@
private final int mFastScrollDistributionMode = FAST_SCROLL_FRACTION_DISTRIBUTE_BY_NUM_SECTIONS;
+ private AppDiscoveryUpdateState mAppDiscoveryUpdateState;
+
/**
* Info about a fast scroller section, depending if sections are merged, the fast scroller
* sections will not be the same set as the section headers.
@@ -106,6 +113,17 @@
return item;
}
+ public static AdapterItem asDiscoveryItem(int pos, String sectionName, AppInfo appInfo,
+ int appIndex) {
+ AdapterItem item = new AdapterItem();
+ item.viewType = AllAppsGridAdapter.VIEW_TYPE_DISCOVERY_ITEM;
+ item.position = pos;
+ item.sectionName = sectionName;
+ item.appInfo = appInfo;
+ item.appIndex = appIndex;
+ return item;
+ }
+
public static AdapterItem asEmptySearch(int pos) {
AdapterItem item = new AdapterItem();
item.viewType = AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH;
@@ -134,6 +152,13 @@
return item;
}
+ public static AdapterItem asLoadingDivider(int pos) {
+ AdapterItem item = new AdapterItem();
+ item.viewType = AllAppsGridAdapter.VIEW_TYPE_APPS_LOADING_DIVIDER;
+ item.position = pos;
+ return item;
+ }
+
public static AdapterItem asMarketSearch(int pos) {
AdapterItem item = new AdapterItem();
item.viewType = AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET;
@@ -142,22 +167,24 @@
}
}
- private Launcher mLauncher;
+ private final Launcher mLauncher;
// The set of apps from the system not including predictions
private final List<AppInfo> mApps = new ArrayList<>();
private final HashMap<ComponentKey, AppInfo> mComponentToAppMap = new HashMap<>();
// The set of filtered apps with the current filter
- private List<AppInfo> mFilteredApps = new ArrayList<>();
+ private final List<AppInfo> mFilteredApps = new ArrayList<>();
// The current set of adapter items
- private List<AdapterItem> mAdapterItems = new ArrayList<>();
+ private final ArrayList<AdapterItem> mAdapterItems = new ArrayList<>();
// The set of sections that we allow fast-scrolling to (includes non-merged sections)
- private List<FastScrollSectionInfo> mFastScrollerSections = new ArrayList<>();
+ private final List<FastScrollSectionInfo> mFastScrollerSections = new ArrayList<>();
// The set of predicted app component names
- private List<ComponentKey> mPredictedAppComponents = new ArrayList<>();
+ private final List<ComponentKey> mPredictedAppComponents = new ArrayList<>();
// The set of predicted apps resolved from the component names and the current set of apps
- private List<AppInfo> mPredictedApps = new ArrayList<>();
+ private final List<AppInfo> mPredictedApps = new ArrayList<>();
+ private final List<AppDiscoveryAppInfo> mDiscoveredApps = new ArrayList<>();
+
// The of ordered component names as a result of a search query
private ArrayList<ComponentKey> mSearchResults;
private HashMap<CharSequence, String> mCachedSectionNames = new HashMap<>();
@@ -240,6 +267,10 @@
return (mSearchResults != null) && mFilteredApps.isEmpty();
}
+ boolean shouldShowEmptySearch() {
+ return hasNoFilteredResults() && !isAppDiscoveryRunning() && mDiscoveredApps.isEmpty();
+ }
+
/**
* Sets the sorted list of filtered components.
*/
@@ -253,6 +284,20 @@
return false;
}
+ public void onAppDiscoverySearchUpdate(@Nullable AppDiscoveryItem app,
+ @NonNull AppDiscoveryUpdateState state) {
+ mAppDiscoveryUpdateState = state;
+ switch (state) {
+ case START:
+ mDiscoveredApps.clear();
+ break;
+ case UPDATE:
+ mDiscoveredApps.add(new AppDiscoveryAppInfo(app));
+ break;
+ }
+ updateAdapterItems();
+ }
+
/**
* Sets the current set of predicted apps. Since this can be called before we get the full set
* of applications, we should merge the results only in onAppsUpdated() which is idempotent.
@@ -350,6 +395,17 @@
* mCachedSectionNames to have been calculated for the set of all apps in mApps.
*/
private void updateAdapterItems() {
+ refillAdapterItems();
+ refreshRecyclerView();
+ }
+
+ private void refreshRecyclerView() {
+ if (mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ private void refillAdapterItems() {
String lastSectionName = null;
FastScrollSectionInfo lastFastScrollerSectionInfo = null;
int position = 0;
@@ -435,14 +491,33 @@
mFilteredApps.add(info);
}
- // Append the search market item if we are currently searching
if (hasFilter()) {
- if (hasNoFilteredResults()) {
- mAdapterItems.add(AdapterItem.asEmptySearch(position++));
+ if (isAppDiscoveryRunning() || mDiscoveredApps.size() > 0) {
+ mAdapterItems.add(AdapterItem.asLoadingDivider(position++));
+ // Append all app discovery results
+ for (int i = 0; i < mDiscoveredApps.size(); i++) {
+ AppDiscoveryAppInfo appDiscoveryAppInfo = mDiscoveredApps.get(i);
+ if (appDiscoveryAppInfo.isRecent) {
+ // already handled in getFilteredAppInfos()
+ continue;
+ }
+ AdapterItem item = AdapterItem.asDiscoveryItem(position++,
+ "", appDiscoveryAppInfo, appIndex++);
+ mAdapterItems.add(item);
+ }
+
+ if (!isAppDiscoveryRunning()) {
+ mAdapterItems.add(AdapterItem.asMarketSearch(position++));
+ }
} else {
- mAdapterItems.add(AdapterItem.asMarketDivider(position++));
+ // Append the search market item
+ if (hasNoFilteredResults()) {
+ mAdapterItems.add(AdapterItem.asEmptySearch(position++));
+ } else {
+ mAdapterItems.add(AdapterItem.asMarketDivider(position++));
+ }
+ mAdapterItems.add(AdapterItem.asMarketSearch(position++));
}
- mAdapterItems.add(AdapterItem.asMarketSearch(position++));
}
if (mNumAppsPerRow != 0) {
@@ -498,11 +573,11 @@
break;
}
}
+ }
- // Refresh the recycler view
- if (mAdapter != null) {
- mAdapter.notifyDataSetChanged();
- }
+ public boolean isAppDiscoveryRunning() {
+ return mAppDiscoveryUpdateState == AppDiscoveryUpdateState.START
+ || mAppDiscoveryUpdateState == AppDiscoveryUpdateState.UPDATE;
}
private List<AppInfo> getFiltersAppInfos() {
@@ -517,6 +592,17 @@
result.add(match);
}
}
+
+ // adding recently used instant apps
+ if (mDiscoveredApps.size() > 0) {
+ for (int i = 0; i < mDiscoveredApps.size(); i++) {
+ AppDiscoveryAppInfo discoveryAppInfo = mDiscoveredApps.get(i);
+ if (discoveryAppInfo.isRecent) {
+ result.add(discoveryAppInfo);
+ }
+ }
+ Collections.sort(result, mAppNameComparator);
+ }
return result;
}
@@ -532,4 +618,5 @@
}
return sectionName;
}
+
}
diff --git a/src/com/android/launcher3/allapps/VerticalPullDetector.java b/src/com/android/launcher3/allapps/VerticalPullDetector.java
index 96e1299..7800c01 100644
--- a/src/com/android/launcher3/allapps/VerticalPullDetector.java
+++ b/src/com/android/launcher3/allapps/VerticalPullDetector.java
@@ -4,6 +4,7 @@
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
+import android.view.animation.Interpolator;
/**
* One dimensional scroll gesture detector for all apps container pull up interaction.
@@ -23,6 +24,9 @@
public static final int DIRECTION_DOWN = 1 << 1;
public static final int DIRECTION_BOTH = DIRECTION_DOWN | DIRECTION_UP;
+ private static final float ANIMATION_DURATION = 1200;
+ private static final float FAST_FLING_PX_MS = 10;
+
/**
* The minimum release velocity in pixels per millisecond that triggers fling..
*/
@@ -112,7 +116,7 @@
mListener = l;
}
- interface Listener {
+ public interface Listener {
void onDragStart(boolean start);
boolean onDrag(float displacement, float velocity);
@@ -272,4 +276,33 @@
private static float interpolate(float from, float to, float alpha) {
return (1.0f - alpha) * from + alpha * to;
}
+
+ public long calculateDuration(float velocity, float progressNeeded) {
+ // TODO: make these values constants after tuning.
+ float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity));
+ float travelDistance = Math.max(0.2f, progressNeeded);
+ long duration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance);
+ if (DBG) {
+ Log.d(TAG, String.format("calculateDuration=%d, v=%f, d=%f", duration, velocity, progressNeeded));
+ }
+ return duration;
+ }
+
+ public static class ScrollInterpolator implements Interpolator {
+
+ boolean mSteeper;
+
+ public void setVelocityAtZero(float velocity) {
+ mSteeper = velocity > FAST_FLING_PX_MS;
+ }
+
+ public float getInterpolation(float t) {
+ t -= 1.0f;
+ float output = t * t * t;
+ if (mSteeper) {
+ output *= t * t; // Make interpolation initial slope steeper
+ }
+ return output + 1;
+ }
+ }
}
diff --git a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java b/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
new file mode 100644
index 0000000..be1e2d6
--- /dev/null
+++ b/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
@@ -0,0 +1,43 @@
+/*
+ * 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.anim;
+
+import android.graphics.Rect;
+
+import com.android.launcher3.util.PillRevealOutlineProvider;
+
+/**
+ * Extension of {@link PillRevealOutlineProvider} which only changes the height of the pill.
+ * For now, we assume the height is added/removed from the bottom.
+ */
+public class PillHeightRevealOutlineProvider extends PillRevealOutlineProvider {
+
+ private final int mNewHeight;
+
+ public PillHeightRevealOutlineProvider(Rect pillRect, float radius, int newHeight) {
+ super(0, 0, pillRect, radius);
+ mOutline.set(pillRect);
+ mNewHeight = newHeight;
+ }
+
+ @Override
+ public void setProgress(float progress) {
+ mOutline.top = 0;
+ int heightDifference = mPillRect.height() - mNewHeight;
+ mOutline.bottom = (int) (mPillRect.bottom - heightDifference * (1 - progress));
+ }
+}
diff --git a/src/com/android/launcher3/anim/PropertyResetListener.java b/src/com/android/launcher3/anim/PropertyResetListener.java
new file mode 100644
index 0000000..eefb014
--- /dev/null
+++ b/src/com/android/launcher3/anim/PropertyResetListener.java
@@ -0,0 +1,41 @@
+/*
+ * 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.anim;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.util.Property;
+
+/**
+ * An AnimatorListener that sets the given property to the given value at the end of the animation.
+ */
+public class PropertyResetListener<T, V> extends AnimatorListenerAdapter {
+
+ private Property<T, V> mPropertyToReset;
+ private V mResetToValue;
+
+ public PropertyResetListener(Property<T, V> propertyToReset, V resetToValue) {
+ mPropertyToReset = propertyToReset;
+ mResetToValue = resetToValue;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPropertyToReset.set((T) ((ObjectAnimator) animation).getTarget(), mResetToValue);
+ }
+}
diff --git a/src/com/android/launcher3/badge/BadgeInfo.java b/src/com/android/launcher3/badge/BadgeInfo.java
index 532396c..08d8ad4 100644
--- a/src/com/android/launcher3/badge/BadgeInfo.java
+++ b/src/com/android/launcher3/badge/BadgeInfo.java
@@ -25,6 +25,7 @@
import android.support.annotation.Nullable;
import com.android.launcher3.notification.NotificationInfo;
+import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.util.PackageUserKey;
import java.util.ArrayList;
@@ -35,6 +36,8 @@
*/
public class BadgeInfo {
+ public static final int MAX_COUNT = 999;
+
/** Used to link this BadgeInfo to icons on the workspace and all apps */
private PackageUserKey mPackageUserKey;
@@ -42,7 +45,13 @@
* The keys of the notifications that this badge represents. These keys can later be
* used to retrieve {@link NotificationInfo}'s.
*/
- private List<String> mNotificationKeys;
+ private List<NotificationKeyData> mNotificationKeys;
+
+ /**
+ * The current sum of the counts in {@link #mNotificationKeys},
+ * updated whenever a key is added or removed.
+ */
+ private int mTotalCount;
/** This will only be initialized if the badge should display the notification icon. */
private NotificationInfo mNotificationInfo;
@@ -59,28 +68,46 @@
}
/**
- * Returns whether the notification was added (false if it already existed).
+ * Returns whether the notification was added or its count changed.
*/
- public boolean addNotificationKeyIfNotExists(String notificationKey) {
- if (mNotificationKeys.contains(notificationKey)) {
- return false;
+ public boolean addOrUpdateNotificationKey(NotificationKeyData notificationKey) {
+ int indexOfPrevKey = mNotificationKeys.indexOf(notificationKey);
+ NotificationKeyData prevKey = indexOfPrevKey == -1 ? null
+ : mNotificationKeys.get(indexOfPrevKey);
+ if (prevKey != null) {
+ if (prevKey.count == notificationKey.count) {
+ return false;
+ }
+ // Notification was updated with a new count.
+ mTotalCount -= prevKey.count;
+ mTotalCount += notificationKey.count;
+ prevKey.count = notificationKey.count;
+ return true;
}
- return mNotificationKeys.add(notificationKey);
+ boolean added = mNotificationKeys.add(notificationKey);
+ if (added) {
+ mTotalCount += notificationKey.count;
+ }
+ return added;
}
/**
* Returns whether the notification was removed (false if it didn't exist).
*/
- public boolean removeNotificationKey(String notificationKey) {
- return mNotificationKeys.remove(notificationKey);
+ public boolean removeNotificationKey(NotificationKeyData notificationKey) {
+ boolean removed = mNotificationKeys.remove(notificationKey);
+ if (removed) {
+ mTotalCount -= notificationKey.count;
+ }
+ return removed;
}
- public List<String> getNotificationKeys() {
+ public List<NotificationKeyData> getNotificationKeys() {
return mNotificationKeys;
}
public int getNotificationCount() {
- return mNotificationKeys.size();
+ return Math.min(mTotalCount, MAX_COUNT);
}
public void setNotificationToShow(@Nullable NotificationInfo notificationInfo) {
diff --git a/src/com/android/launcher3/badge/BadgeRenderer.java b/src/com/android/launcher3/badge/BadgeRenderer.java
index 8bbc2af..5896928 100644
--- a/src/com/android/launcher3/badge/BadgeRenderer.java
+++ b/src/com/android/launcher3/badge/BadgeRenderer.java
@@ -20,14 +20,15 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.graphics.IconPalette;
+import com.android.launcher3.graphics.ShadowGenerator;
/**
* Contains parameters necessary to draw a badge for an icon (e.g. the size of the badge).
@@ -40,10 +41,12 @@
private final int mTextHeight;
private final IconDrawer mLargeIconDrawer;
private final IconDrawer mSmallIconDrawer;
- private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG
+ | Paint.FILTER_BITMAP_FLAG);
+ private final Bitmap mBackgroundWithShadow;
- public BadgeRenderer(Context context) {
+ public BadgeRenderer(final Context context) {
mContext = context;
Resources res = context.getResources();
mSize = res.getDimensionPixelSize(R.dimen.badge_size);
@@ -51,10 +54,13 @@
mSmallIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_large_padding));
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.badge_text_size));
+ mTextPaint.setFakeBoldText(true);
// Measure the text height.
Rect tempTextHeight = new Rect();
mTextPaint.getTextBounds("0", 0, 1, tempTextHeight);
mTextHeight = tempTextHeight.height();
+
+ mBackgroundWithShadow = ShadowGenerator.createCircleWithShadow(Color.WHITE, mSize);
}
/**
@@ -67,13 +73,15 @@
*/
public void draw(Canvas canvas, IconPalette palette, @Nullable BadgeInfo badgeInfo,
Rect iconBounds, float badgeScale) {
- mBackgroundPaint.setColor(palette.backgroundColor);
mTextPaint.setColor(palette.textColor);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
// We draw the badge relative to its center.
canvas.translate(iconBounds.right - mSize / 2, iconBounds.top + mSize / 2);
canvas.scale(badgeScale, badgeScale);
- canvas.drawCircle(0, 0, mSize / 2, mBackgroundPaint);
+ mBackgroundPaint.setColorFilter(palette.backgroundColorMatrixFilter);
+ int backgroundSize = mBackgroundWithShadow.getHeight(); // Same as width.
+ canvas.drawBitmap(mBackgroundWithShadow, -backgroundSize / 2, -backgroundSize / 2,
+ mBackgroundPaint);
IconDrawer iconDrawer = badgeInfo != null && badgeInfo.isIconLarge()
? mLargeIconDrawer : mSmallIconDrawer;
Shader icon = badgeInfo == null ? null : badgeInfo.getNotificationIconForBadge(
diff --git a/src/com/android/launcher3/badge/FolderBadgeInfo.java b/src/com/android/launcher3/badge/FolderBadgeInfo.java
index 4d1e5c2..f7c64aa 100644
--- a/src/com/android/launcher3/badge/FolderBadgeInfo.java
+++ b/src/com/android/launcher3/badge/FolderBadgeInfo.java
@@ -18,8 +18,6 @@
import com.android.launcher3.Utilities;
-import static com.android.launcher3.Utilities.boundToRange;
-
/**
* Subclass of BadgeInfo that only contains the badge count,
* which is the sum of all the Folder's items' counts.
@@ -27,7 +25,6 @@
public class FolderBadgeInfo extends BadgeInfo {
private static final int MIN_COUNT = 0;
- private static final int MAX_COUNT = 999;
private int mTotalNotificationCount;
@@ -41,7 +38,7 @@
}
mTotalNotificationCount += badgeToAdd.getNotificationCount();
mTotalNotificationCount = Utilities.boundToRange(
- mTotalNotificationCount, MIN_COUNT, MAX_COUNT);
+ mTotalNotificationCount, MIN_COUNT, BadgeInfo.MAX_COUNT);
}
public void subtractBadgeInfo(BadgeInfo badgeToSubtract) {
@@ -50,7 +47,7 @@
}
mTotalNotificationCount -= badgeToSubtract.getNotificationCount();
mTotalNotificationCount = Utilities.boundToRange(
- mTotalNotificationCount, MIN_COUNT, MAX_COUNT);
+ mTotalNotificationCount, MIN_COUNT, BadgeInfo.MAX_COUNT);
}
@Override
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 44a3686..2eb5b02 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -73,7 +73,8 @@
UserHandle user);
public abstract void startActivityForProfile(ComponentName component, UserHandle user,
Rect sourceBounds, Bundle opts);
- public abstract ApplicationInfo getApplicationInfo(String packageName, UserHandle user);
+ public abstract ApplicationInfo getApplicationInfo(
+ String packageName, int flags, UserHandle user);
public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user);
public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 776f593..4590173 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -27,6 +27,7 @@
import android.content.pm.ShortcutInfo;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.Process;
import android.os.UserHandle;
import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVL;
@@ -66,9 +67,29 @@
}
@Override
- public ApplicationInfo getApplicationInfo(String packageName, UserHandle user) {
- List<LauncherActivityInfo> activityList = mLauncherApps.getActivityList(packageName, user);
- return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
+ public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
+ final boolean isPrimaryUser = Process.myUserHandle().equals(user);
+ if (!isPrimaryUser && (flags == 0)) {
+ // We are looking for an installed app on a secondary profile. Prior to O, the only
+ // entry point for work profiles is through the LauncherActivity.
+ List<LauncherActivityInfo> activityList =
+ mLauncherApps.getActivityList(packageName, user);
+ return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
+ }
+ try {
+ ApplicationInfo info =
+ mContext.getPackageManager().getApplicationInfo(packageName, flags);
+ // There is no way to check if the app is installed for managed profile. But for
+ // primary profile, we can still have this check.
+ if (isPrimaryUser && ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0)
+ || !info.enabled) {
+ return null;
+ }
+ return info;
+ } catch (PackageManager.NameNotFoundException e) {
+ // Package not found
+ return null;
+ }
}
@Override
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
index 377907a..d7e35a2 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
@@ -20,6 +20,8 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
+import android.os.Build;
+import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
@@ -35,22 +37,29 @@
}
@Override
- public ApplicationInfo getApplicationInfo(String packageName, UserHandle user) {
- return mLauncherApps.getApplicationInfo(packageName, 0, user);
+ public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
+ ApplicationInfo info = mLauncherApps.getApplicationInfo(packageName, flags, user);
+ return info == null || (info.flags & ApplicationInfo.FLAG_INSTALLED) == 0 || !info.enabled
+ ? null : info;
}
@Override
public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList() {
List<ShortcutConfigActivityInfo> result = new ArrayList<>();
+ UserHandle myUser = Process.myUserHandle();
try {
Method m = LauncherApps.class.getDeclaredMethod("getShortcutConfigActivityList",
String.class, UserHandle.class);
for (UserHandle user : UserManagerCompat.getInstance(mContext).getUserProfiles()) {
+ boolean ignoreTargetSdk = myUser.equals(user);
List<LauncherActivityInfo> activities =
(List<LauncherActivityInfo>) m.invoke(mLauncherApps, null, user);
for (LauncherActivityInfo activityInfo : activities) {
- result.add(new ShortcutConfigActivityInfoVO(activityInfo));
+ if (ignoreTargetSdk || activityInfo.getApplicationInfo().targetSdkVersion >=
+ Build.VERSION_CODES.O) {
+ result.add(new ShortcutConfigActivityInfoVO(activityInfo));
+ }
}
}
} catch (Exception e) {
diff --git a/src/com/android/launcher3/compat/PinItemRequestCompat.java b/src/com/android/launcher3/compat/PinItemRequestCompat.java
index f76b776..1308cba 100644
--- a/src/com/android/launcher3/compat/PinItemRequestCompat.java
+++ b/src/com/android/launcher3/compat/PinItemRequestCompat.java
@@ -24,6 +24,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.launcher3.Utilities;
+
/**
* A wrapper around platform implementation of PinItemRequestCompat until the
* updated SDK is available.
@@ -76,6 +78,14 @@
}
}
+ public Bundle getExtras() {
+ try {
+ return (Bundle) mObject.getClass().getDeclaredMethod("getExtras").invoke(mObject);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
private Object invokeMethod(String methodName) {
try {
return mObject.getClass().getDeclaredMethod(methodName).invoke(mObject);
@@ -107,6 +117,9 @@
};
public static PinItemRequestCompat getPinItemRequest(Intent intent) {
+ if (!Utilities.isAtLeastO()) {
+ return null;
+ }
Parcelable extra = intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST);
return extra == null ? null : new PinItemRequestCompat(extra);
}
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java b/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java
new file mode 100644
index 0000000..06493b2
--- /dev/null
+++ b/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java
@@ -0,0 +1,71 @@
+/*
+ * 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.discovery;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.ShortcutInfo;
+
+public class AppDiscoveryAppInfo extends AppInfo {
+
+ public final boolean showAsDiscoveryItem;
+ public final boolean isInstantApp;
+ public final boolean isRecent;
+ public final float rating;
+ public final long reviewCount;
+ public final @NonNull String publisher;
+ public final @NonNull Intent installIntent;
+ public final @NonNull Intent launchIntent;
+ public final @Nullable String priceFormatted;
+
+ public AppDiscoveryAppInfo(AppDiscoveryItem item) {
+ this.intent = item.isInstantApp ? item.launchIntent : item.installIntent;
+ this.title = item.title;
+ this.iconBitmap = item.bitmap;
+ this.isDisabled = ShortcutInfo.DEFAULT;
+ this.usingLowResIcon = false;
+ this.isInstantApp = item.isInstantApp;
+ this.isRecent = item.isRecent;
+ this.rating = item.starRating;
+ this.showAsDiscoveryItem = true;
+ this.publisher = item.publisher != null ? item.publisher : "";
+ this.priceFormatted = item.price;
+ this.componentName = new ComponentName(item.packageName, "");
+ this.installIntent = item.installIntent;
+ this.launchIntent = item.launchIntent;
+ this.reviewCount = item.reviewCount;
+ this.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+ }
+
+ @Override
+ public ShortcutInfo makeShortcut() {
+ if (!isDragAndDropSupported()) {
+ throw new RuntimeException("DnD is currently not supported for discovered store apps");
+ }
+ return super.makeShortcut();
+ }
+
+ public boolean isDragAndDropSupported() {
+ return isInstantApp;
+ }
+
+}
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItem.java b/src/com/android/launcher3/discovery/AppDiscoveryItem.java
new file mode 100644
index 0000000..09c91ac
--- /dev/null
+++ b/src/com/android/launcher3/discovery/AppDiscoveryItem.java
@@ -0,0 +1,65 @@
+/*
+ * 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.discovery;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+
+/**
+ * This class represents the model for a discovered app via app discovery.
+ * It holds all information for one result retrieved from an app discovery service.
+ */
+public class AppDiscoveryItem {
+
+ public final String packageName;
+ public final boolean isInstantApp;
+ public final boolean isRecent;
+ public final float starRating;
+ public final long reviewCount;
+ public final Intent launchIntent;
+ public final Intent installIntent;
+ public final CharSequence title;
+ public final String publisher;
+ public final String price;
+ public final Bitmap bitmap;
+
+ public AppDiscoveryItem(String packageName,
+ boolean isInstantApp,
+ boolean isRecent,
+ float starRating,
+ long reviewCount,
+ CharSequence title,
+ String publisher,
+ Bitmap bitmap,
+ String price,
+ Intent launchIntent,
+ Intent installIntent) {
+ this.packageName = packageName;
+ this.isInstantApp = isInstantApp;
+ this.isRecent = isRecent;
+ this.starRating = starRating;
+ this.reviewCount = reviewCount;
+ this.launchIntent = launchIntent;
+ this.installIntent = installIntent;
+ this.title = title;
+ this.publisher = publisher;
+ this.price = price;
+ this.bitmap = bitmap;
+ }
+
+}
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItemView.java b/src/com/android/launcher3/discovery/AppDiscoveryItemView.java
new file mode 100644
index 0000000..9bb3b10
--- /dev/null
+++ b/src/com/android/launcher3/discovery/AppDiscoveryItemView.java
@@ -0,0 +1,97 @@
+/*
+ * 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.discovery;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.android.launcher3.R;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+public class AppDiscoveryItemView extends RelativeLayout {
+
+ private static boolean SHOW_REVIEW_COUNT = false;
+
+ private ImageView mImage;
+ private TextView mTitle;
+ private TextView mRatingText;
+ private RatingView mRatingView;
+ private TextView mReviewCount;
+ private TextView mPrice;
+ private OnLongClickListener mOnLongClickListener;
+
+ public AppDiscoveryItemView(Context context) {
+ this(context, null);
+ }
+
+ public AppDiscoveryItemView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public AppDiscoveryItemView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ this.mImage = (ImageView) findViewById(R.id.image);
+ this.mTitle = (TextView) findViewById(R.id.title);
+ this.mRatingText = (TextView) findViewById(R.id.rating);
+ this.mRatingView = (RatingView) findViewById(R.id.rating_view);
+ this.mPrice = (TextView) findViewById(R.id.price);
+ this.mReviewCount = (TextView) findViewById(R.id.review_count);
+ }
+
+ public void init(OnClickListener clickListener,
+ AccessibilityDelegate accessibilityDelegate,
+ OnLongClickListener onLongClickListener) {
+ setOnClickListener(clickListener);
+ mImage.setOnClickListener(clickListener);
+ setAccessibilityDelegate(accessibilityDelegate);
+ mOnLongClickListener = onLongClickListener;
+ }
+
+ public void apply(@NonNull AppDiscoveryAppInfo info) {
+ setTag(info);
+ mImage.setTag(info);
+ mImage.setImageBitmap(info.iconBitmap);
+ mImage.setOnLongClickListener(info.isDragAndDropSupported() ? mOnLongClickListener : null);
+ mTitle.setText(info.title);
+ mPrice.setText(info.priceFormatted != null ? info.priceFormatted : "");
+ mReviewCount.setVisibility(SHOW_REVIEW_COUNT ? View.VISIBLE : View.GONE);
+ if (info.rating >= 0) {
+ mRatingText.setText(new DecimalFormat("#.#").format(info.rating));
+ mRatingView.setRating(info.rating);
+ mRatingView.setVisibility(View.VISIBLE);
+ String reviewCountFormatted = NumberFormat.getInstance().format(info.reviewCount);
+ mReviewCount.setText("(" + reviewCountFormatted + ")");
+ } else {
+ // if we don't have a rating
+ mRatingView.setVisibility(View.GONE);
+ mRatingText.setText("");
+ mReviewCount.setText("");
+ }
+ }
+}
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryUpdateState.java b/src/com/android/launcher3/discovery/AppDiscoveryUpdateState.java
new file mode 100644
index 0000000..0700a10
--- /dev/null
+++ b/src/com/android/launcher3/discovery/AppDiscoveryUpdateState.java
@@ -0,0 +1,21 @@
+/*
+ * 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.discovery;
+
+public enum AppDiscoveryUpdateState {
+ START, UPDATE, END
+}
diff --git a/src/com/android/launcher3/discovery/RatingView.java b/src/com/android/launcher3/discovery/RatingView.java
new file mode 100644
index 0000000..8fe63d6
--- /dev/null
+++ b/src/com/android/launcher3/discovery/RatingView.java
@@ -0,0 +1,94 @@
+/*
+ * 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.discovery;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.ClipDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+
+import com.android.launcher3.R;
+
+/**
+ * A simple rating view that shows stars with a rating from 0-5.
+ */
+public class RatingView extends View {
+
+ private static final float WIDTH_FACTOR = 0.9f;
+ private static final int MAX_LEVEL = 10000;
+ private static final int MAX_STARS = 5;
+
+ private final Drawable mStarDrawable;
+ private final int mColorGray;
+ private final int mColorHighlight;
+
+ private float rating;
+
+ public RatingView(Context context) {
+ this(context, null);
+ }
+
+ public RatingView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public RatingView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mStarDrawable = getResources().getDrawable(R.drawable.ic_star_rating, null);
+ mColorGray = 0x1E000000;
+ mColorHighlight = 0x8A000000;
+ }
+
+ public void setRating(float rating) {
+ this.rating = Math.min(Math.max(rating, 0), MAX_STARS);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ drawStars(canvas, MAX_STARS, mColorGray);
+ drawStars(canvas, rating, mColorHighlight);
+ }
+
+ private void drawStars(Canvas canvas, float stars, int color) {
+ int fullWidth = getLayoutParams().width;
+ int cellWidth = fullWidth / MAX_STARS;
+ int starWidth = (int) (cellWidth * WIDTH_FACTOR);
+ int padding = cellWidth - starWidth;
+ int fullStars = (int) stars;
+ float partialStarFactor = stars - fullStars;
+
+ for (int i = 0; i < fullStars; i++) {
+ int x = i * cellWidth + padding;
+ Drawable star = mStarDrawable.getConstantState().newDrawable().mutate();
+ star.setTint(color);
+ star.setBounds(x, padding, x + starWidth, padding + starWidth);
+ star.draw(canvas);
+ }
+ if (partialStarFactor > 0f) {
+ int x = fullStars * cellWidth + padding;
+ ClipDrawable star = new ClipDrawable(mStarDrawable,
+ Gravity.LEFT, ClipDrawable.HORIZONTAL);
+ star.setTint(color);
+ star.setLevel((int) (MAX_LEVEL * partialStarFactor));
+ star.setBounds(x, padding, x + starWidth, padding + starWidth);
+ star.draw(canvas);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index b80baf3..c2a4820 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -27,10 +27,8 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.*;
@@ -47,7 +45,6 @@
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.widget.PendingAddWidgetInfo;
-import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetImageView;
@@ -65,7 +62,7 @@
private LauncherAppState mApp;
private InvariantDeviceProfile mIdp;
- private WidgetCell mWidgetCell;
+ private LivePreviewWidgetCell mWidgetCell;
// Widget request specific options.
private AppWidgetHost mAppWidgetHost;
@@ -92,7 +89,7 @@
mDeviceProfile = mIdp.getDeviceProfile(getApplicationContext());
setContentView(R.layout.add_item_confirmation_activity);
- mWidgetCell = (WidgetCell) findViewById(R.id.widget_cell);
+ mWidgetCell = (LivePreviewWidgetCell) findViewById(R.id.widget_cell);
if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
setupShortcut();
@@ -169,6 +166,7 @@
// Cannot add widget
return false;
}
+ mWidgetCell.setPreview(PinItemDragListener.getPreview(mRequest));
mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
mAppWidgetHost = new AppWidgetHost(this, Launcher.APPWIDGET_HOST_ID);
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index e4c9be4..7806c98 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -24,7 +24,6 @@
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
@@ -36,6 +35,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import java.util.Arrays;
@@ -259,7 +259,7 @@
m1.setSaturation(0);
ColorMatrix m2 = new ColorMatrix();
- setColorScale(color, m2);
+ Themes.setColorScaleOnMatrix(color, m2);
m1.postConcat(m2);
animateFilterTo(m1.getArray());
@@ -384,11 +384,6 @@
}
}
- public static void setColorScale(int color, ColorMatrix target) {
- target.setScale(Color.red(color) / 255f, Color.green(color) / 255f,
- Color.blue(color) / 255f, Color.alpha(color) / 255f);
- }
-
public int getBlurSizeOutline() {
return mBlurSizeOutline;
}
diff --git a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
new file mode 100644
index 0000000..36a0292
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
@@ -0,0 +1,99 @@
+package com.android.launcher3.dragndrop;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.RemoteViews;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.widget.WidgetCell;
+
+/**
+ * Extension of {@link WidgetCell} which supports generating previews from {@link RemoteViews}
+ */
+public class LivePreviewWidgetCell extends WidgetCell {
+
+ private RemoteViews mPreview;
+
+ public LivePreviewWidgetCell(Context context) {
+ this(context, null);
+ }
+
+ public LivePreviewWidgetCell(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LivePreviewWidgetCell(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setPreview(RemoteViews view) {
+ mPreview = view;
+ }
+
+ @Override
+ public void ensurePreview() {
+ if (mPreview != null && mActiveRequest == null) {
+ Bitmap preview = generateFromRemoteViews(
+ mActivity, mPreview, mItem.widgetInfo, mPresetPreviewSize, new int[1]);
+ if (preview != null) {
+ applyPreview(preview);
+ return;
+ }
+ }
+ super.ensurePreview();
+ }
+
+ /**
+ * Generates a bitmap by inflating {@param views}.
+ * @see com.android.launcher3.WidgetPreviewLoader#generateWidgetPreview
+ *
+ * TODO: Consider moving this to the background thread.
+ */
+ public static Bitmap generateFromRemoteViews(BaseActivity activity, RemoteViews views,
+ LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) {
+
+ DeviceProfile dp = activity.getDeviceProfile();
+ int viewWidth = dp.cellWidthPx * info.spanX;
+ int viewHeight = dp.cellHeightPx * info.spanY;
+
+ final View v;
+ try {
+ v = views.apply(activity, new FrameLayout(activity));
+ v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));
+
+ viewWidth = v.getMeasuredWidth();
+ viewHeight = v.getMeasuredHeight();
+ v.layout(0, 0, viewWidth, viewHeight);
+ } catch (Exception e) {
+ return null;
+ }
+
+ preScaledWidthOut[0] = viewWidth;
+ final int bitmapWidth, bitmapHeight;
+ final float scale;
+ if (viewWidth > previewSize) {
+ scale = ((float) previewSize) / viewWidth;
+ bitmapWidth = previewSize;
+ bitmapHeight = (int) (viewHeight * scale);
+ } else {
+ scale = 1;
+ bitmapWidth = viewWidth;
+ bitmapHeight = viewHeight;
+ }
+
+ Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(preview);
+ c.scale(scale, scale);
+ v.draw(c);
+ c.setBitmap(null);
+ return preview;
+ }
+}
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index 6e5318f..fd252a2 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -16,9 +16,11 @@
package com.android.launcher3.dragndrop;
+import android.appwidget.AppWidgetManager;
import android.content.ClipDescription;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
@@ -27,6 +29,7 @@
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
+import android.widget.RemoteViews;
import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DragSource;
@@ -171,7 +174,12 @@
// and the absolute position (position relative to the screen) of drag event is same
// across windows, using drag position here give a good estimate for relative position
// to source window.
- new PendingItemDragHelper(view).startDrag(new Rect(mPreviewRect),
+ PendingItemDragHelper dragHelper = new PendingItemDragHelper(view);
+ if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_APPWIDGET) {
+ dragHelper.setPreview(getPreview(mRequest));
+ }
+
+ dragHelper.startDrag(new Rect(mPreviewRect),
mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
mDragStartTime = SystemClock.uptimeMillis();
return true;
@@ -250,6 +258,15 @@
}
}
+ public static RemoteViews getPreview(PinItemRequestCompat request) {
+ Bundle extras = request.getExtras();
+ if (extras != null &&
+ extras.get(AppWidgetManager.EXTRA_APPWIDGET_PREVIEW) instanceof RemoteViews) {
+ return (RemoteViews) extras.get(AppWidgetManager.EXTRA_APPWIDGET_PREVIEW);
+ }
+ return null;
+ }
+
public static final Parcelable.Creator<PinItemDragListener> CREATOR =
new Parcelable.Creator<PinItemDragListener>() {
public PinItemDragListener createFromParcel(Parcel source) {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 2695594..3d2ffb4 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -56,7 +56,6 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LogDecelerateInterpolator;
import com.android.launcher3.OnAlarmListener;
@@ -74,7 +73,6 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.pageindicators.PageIndicatorDots;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.CircleRevealOutlineProvider;
@@ -249,8 +247,11 @@
}
mFolderName.setOnEditorActionListener(this);
mFolderName.setSelectAllOnFocus(true);
- mFolderName.setInputType(mFolderName.getInputType() |
- InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
+ mFolderName.setInputType(mFolderName.getInputType()
+ & ~InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
+ & ~InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
+ | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
+ mFolderName.forceDisableSuggestions(true);
mFooter = findViewById(R.id.folder_footer);
@@ -1412,7 +1413,7 @@
}
@Override
- public void prepareAutoAdd() {
+ public void prepareAutoUpdate() {
close(false);
}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index fce902e..f216010 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -24,11 +24,15 @@
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.util.AttributeSet;
@@ -125,8 +129,6 @@
private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<PreviewItemDrawingParams>();
private Drawable mReferenceDrawable = null;
- Paint mBgPaint = new Paint();
-
private Alarm mOpenAlarm = new Alarm();
private FolderBadgeInfo mBadgeInfo = new FolderBadgeInfo();
@@ -179,11 +181,6 @@
DeviceProfile grid = launcher.getDeviceProfile();
FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
- // For performance and compatibility reasons we render the preview using a software layer.
- // In particular, hardware path clipping has spotty ecosystem support and bad performance.
- // Software rendering also allows us to use shadow layers.
- icon.setLayerType(LAYER_TYPE_SOFTWARE, new Paint(Paint.FILTER_BITMAP_FLAG));
-
icon.setClipToPadding(false);
icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name);
icon.mFolderName.setText(folderInfo.title);
@@ -493,7 +490,7 @@
}
private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) {
- canvas.save();
+ canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(params.transX, params.transY);
canvas.scale(params.scale, params.scale);
Drawable d = params.drawable;
@@ -520,10 +517,29 @@
* information, handles drawing, and animation (accept state <--> rest state).
*/
public static class PreviewBackground {
+
+ private final PorterDuffXfermode mClipPorterDuffXfermode
+ = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
+ // Create a RadialGradient such that it draws a black circle and then extends with
+ // transparent. To achieve this, we keep the gradient to black for the range [0, 1) and
+ // just at the edge quickly change it to transparent.
+ private final RadialGradient mClipShader = new RadialGradient(0, 0, 1,
+ new int[] {Color.BLACK, Color.BLACK, Color.TRANSPARENT },
+ new float[] {0, 0.999f, 1},
+ Shader.TileMode.CLAMP);
+
+ private final PorterDuffXfermode mShadowPorterDuffXfermode
+ = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
+ private RadialGradient mShadowShader = null;
+
+ private final Matrix mShaderMatrix = new Matrix();
+ private final Path mPath = new Path();
+
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
private float mScale = 1f;
private float mColorMultiplier = 1f;
- private Path mClipPath = new Path();
- private int mStrokeWidth;
+ private float mStrokeWidth;
private View mInvalidateDelegate;
public int previewSize;
@@ -546,7 +562,7 @@
private static final int BG_OPACITY = 160;
private static final int MAX_BG_OPACITY = 225;
private static final int BG_INTENSITY = 245;
- private static final int SHADOW_OPACITY = 80;
+ private static final int SHADOW_OPACITY = 40;
ValueAnimator mScaleAnimator;
@@ -562,7 +578,16 @@
basePreviewOffsetX = (availableSpace - this.previewSize) / 2;
basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding;
- mStrokeWidth = Utilities.pxFromDp(1, dm);
+ // Stroke width is 1dp
+ mStrokeWidth = dm.density;
+
+ float radius = getScaledRadius();
+ float shadowRadius = radius + mStrokeWidth;
+ int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
+ mShadowShader = new RadialGradient(0, 0, 1,
+ new int[] {shadowColor, Color.TRANSPARENT},
+ new float[] {radius / shadowRadius, 1},
+ Shader.TileMode.CLAMP);
invalidate();
}
@@ -592,10 +617,6 @@
}
void invalidate() {
- int radius = getScaledRadius();
- mClipPath.reset();
- mClipPath.addCircle(radius, radius, radius, Path.Direction.CW);
-
if (mInvalidateDelegate != null) {
mInvalidateDelegate.invalidate();
}
@@ -610,70 +631,94 @@
invalidate();
}
- public void drawBackground(Canvas canvas, Paint paint) {
- canvas.save();
- canvas.translate(getOffsetX(), getOffsetY());
-
- paint.reset();
- paint.setStyle(Paint.Style.FILL);
- paint.setXfermode(null);
- paint.setAntiAlias(true);
-
+ public void drawBackground(Canvas canvas) {
+ mPaint.setStyle(Paint.Style.FILL);
int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
- paint.setColor(Color.argb(alpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+ mPaint.setColor(Color.argb(alpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+ drawCircle(canvas, 0 /* deltaRadius */);
+
+ // Draw shadow.
+ if (mShadowShader == null) {
+ return;
+ }
float radius = getScaledRadius();
+ float shadowRadius = radius + mStrokeWidth;
+ mPaint.setColor(Color.BLACK);
+ int offsetX = getOffsetX();
+ int offsetY = getOffsetY();
+ final int saveCount;
+ if (canvas.isHardwareAccelerated()) {
+ saveCount = canvas.saveLayer(offsetX - mStrokeWidth, offsetY,
+ offsetX + radius + shadowRadius, offsetY + shadowRadius + shadowRadius,
+ null, Canvas.CLIP_TO_LAYER_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
- canvas.drawCircle(radius, radius, radius, paint);
- canvas.clipPath(mClipPath, Region.Op.DIFFERENCE);
+ } else {
+ saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
+ clipCanvasSoftware(canvas, Region.Op.DIFFERENCE);
+ }
- paint.setStyle(Paint.Style.STROKE);
- paint.setColor(Color.TRANSPARENT);
- paint.setShadowLayer(mStrokeWidth, 0, mStrokeWidth, Color.argb(SHADOW_OPACITY, 0, 0, 0));
- canvas.drawCircle(radius, radius, radius, paint);
+ mShaderMatrix.setScale(shadowRadius, shadowRadius);
+ mShaderMatrix.postTranslate(radius + offsetX, shadowRadius + offsetY);
+ mShadowShader.setLocalMatrix(mShaderMatrix);
+ mPaint.setShader(mShadowShader);
+ canvas.drawPaint(mPaint);
+ mPaint.setShader(null);
- canvas.restore();
+ if (canvas.isHardwareAccelerated()) {
+ mPaint.setXfermode(mShadowPorterDuffXfermode);
+ canvas.drawCircle(radius + offsetX, radius + offsetY, radius, mPaint);
+ mPaint.setXfermode(null);
+ }
+
+ canvas.restoreToCount(saveCount);
}
- public void drawBackgroundStroke(Canvas canvas, Paint paint) {
- canvas.save();
- canvas.translate(getOffsetX(), getOffsetY());
-
- paint.reset();
- paint.setAntiAlias(true);
- paint.setColor(Color.argb(255, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(mStrokeWidth);
-
- float radius = getScaledRadius();
- canvas.drawCircle(radius, radius, radius - 1, paint);
-
- canvas.restore();
+ public void drawBackgroundStroke(Canvas canvas) {
+ mPaint.setColor(Color.argb(255, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ drawCircle(canvas, 1 /* deltaRadius */);
}
- public void drawLeaveBehind(Canvas canvas, Paint paint) {
+ public void drawLeaveBehind(Canvas canvas) {
float originalScale = mScale;
mScale = 0.5f;
- canvas.save();
- canvas.translate(getOffsetX(), getOffsetY());
+ mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setColor(Color.argb(160, 245, 245, 245));
+ drawCircle(canvas, 0 /* deltaRadius */);
- paint.reset();
- paint.setAntiAlias(true);
- paint.setColor(Color.argb(160, 245, 245, 245));
-
- float radius = getScaledRadius();
- canvas.drawCircle(radius, radius, radius, paint);
-
- canvas.restore();
mScale = originalScale;
}
- // It is the callers responsibility to save and restore the canvas.
- private void clipCanvas(Canvas canvas) {
- canvas.translate(getOffsetX(), getOffsetY());
- canvas.clipPath(mClipPath);
- canvas.translate(-getOffsetX(), -getOffsetY());
+ private void drawCircle(Canvas canvas,float deltaRadius) {
+ float radius = getScaledRadius();
+ canvas.drawCircle(radius + getOffsetX(), radius + getOffsetY(),
+ radius - deltaRadius, mPaint);
+ }
+
+ // It is the callers responsibility to save and restore the canvas layers.
+ private void clipCanvasSoftware(Canvas canvas, Region.Op op) {
+ mPath.reset();
+ float r = getScaledRadius();
+ mPath.addCircle(r + getOffsetX(), r + getOffsetY(), r, Path.Direction.CW);
+ canvas.clipPath(mPath, op);
+ }
+
+ // It is the callers responsibility to save and restore the canvas layers.
+ private void clipCanvasHardware(Canvas canvas) {
+ mPaint.setColor(Color.BLACK);
+ mPaint.setXfermode(mClipPorterDuffXfermode);
+
+ float radius = getScaledRadius();
+ mShaderMatrix.setScale(radius, radius);
+ mShaderMatrix.postTranslate(radius + getOffsetX(), radius + getOffsetY());
+ mClipShader.setLocalMatrix(mShaderMatrix);
+ mPaint.setShader(mClipShader);
+ canvas.drawPaint(mPaint);
+ mPaint.setXfermode(null);
+ mPaint.setShader(null);
}
private void delegateDrawing(CellLayout delegate, int cellX, int cellY) {
@@ -793,17 +838,22 @@
}
if (!mBackground.drawingDelegated()) {
- mBackground.drawBackground(canvas, mBgPaint);
+ mBackground.drawBackground(canvas);
}
if (mFolder == null) return;
if (mFolder.getItemCount() == 0 && !mAnimating) return;
- canvas.save();
+ final int saveCount;
-
- if (mPreviewLayoutRule.clipToBackground()) {
- mBackground.clipCanvas(canvas);
+ if (canvas.isHardwareAccelerated()) {
+ saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
+ Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+ } else {
+ saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
+ if (mPreviewLayoutRule.clipToBackground()) {
+ mBackground.clipCanvasSoftware(canvas, Region.Op.INTERSECT);
+ }
}
// The items are drawn in coordinates relative to the preview offset
@@ -816,18 +866,24 @@
drawPreviewItem(canvas, p);
}
}
- canvas.restore();
+ canvas.translate(-mBackground.basePreviewOffsetX, -mBackground.basePreviewOffsetY);
+
+ if (mPreviewLayoutRule.clipToBackground() && canvas.isHardwareAccelerated()) {
+ mBackground.clipCanvasHardware(canvas);
+ }
+ canvas.restoreToCount(saveCount);
if (mPreviewLayoutRule.clipToBackground() && !mBackground.drawingDelegated()) {
- mBackground.drawBackgroundStroke(canvas, mBgPaint);
+ mBackground.drawBackgroundStroke(canvas);
}
- int offsetX = mBackground.getOffsetX();
- int offsetY = mBackground.getOffsetY();
- int previewSize = (int) (mBackground.previewSize * mBackground.mScale);
- Rect bounds = new Rect(offsetX, offsetY, offsetX + previewSize, offsetY + previewSize);
if ((mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) || mBadgeScale > 0) {
// If we are animating to the accepting state, animate the badge out.
+ int offsetX = mBackground.getOffsetX();
+ int offsetY = mBackground.getOffsetY();
+ int previewSize = (int) (mBackground.previewSize * mBackground.mScale);
+ Rect bounds = new Rect(offsetX, offsetY, offsetX + previewSize, offsetY + previewSize);
+
float badgeScale = Math.max(0, mBadgeScale - mBackground.getScaleProgress());
mBadgeRenderer.draw(canvas, IconPalette.FOLDER_ICON_PALETTE, mBadgeInfo, bounds, badgeScale);
}
@@ -981,7 +1037,7 @@
}
@Override
- public void prepareAutoAdd() {
+ public void prepareAutoUpdate() {
}
@Override
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index 8b207bb..60bbce4 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -85,10 +85,10 @@
if (Utilities.isAtLeastO()) {
try {
// Try to load the path from Mask Icon
- Drawable maskIcon = context.getDrawable(R.drawable.mask_drawable_wrapper);
- maskIcon.setBounds(0, 0,
+ Drawable icon = context.getDrawable(R.drawable.adaptive_icon_drawable_wrapper);
+ icon.setBounds(0, 0,
PreloadIconDrawable.PATH_SIZE, PreloadIconDrawable.PATH_SIZE);
- return (Path) maskIcon.getClass().getMethod("getIconMask").invoke(maskIcon);
+ return (Path) icon.getClass().getMethod("getIconMask").invoke(icon);
} catch (Exception e) {
Log.e(TAG, "Error loading mask icon", e);
}
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index 23c6a12..cd7cf70 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -19,11 +19,12 @@
import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
import android.support.v4.graphics.ColorUtils;
import android.util.Log;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.util.Themes;
/**
@@ -41,12 +42,16 @@
public final int dominantColor;
public final int backgroundColor;
+ public final ColorMatrixColorFilter backgroundColorMatrixFilter;
public final int textColor;
public final int secondaryColor;
private IconPalette(int color) {
dominantColor = color;
backgroundColor = getMutedColor(dominantColor);
+ ColorMatrix backgroundColorMatrix = new ColorMatrix();
+ Themes.setColorScaleOnMatrix(backgroundColor, backgroundColorMatrix);
+ backgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix);
textColor = getTextColorForBackground(backgroundColor);
secondaryColor = getLowContrastColor(backgroundColor);
}
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 1a50dfe..ef54661 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -40,7 +40,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@@ -166,7 +165,7 @@
* @param scale the scale to apply before drawing {@param icon} on the canvas
*/
public static Bitmap createIconBitmap(Drawable icon, Context context, float scale) {
- icon = wrapToMaskableIconDrawable(context, icon);
+ icon = wrapToAdaptiveIconDrawable(context, icon);
synchronized (sCanvas) {
final int iconBitmapSize = LauncherAppState.getIDP(context).iconBitmapSize;
@@ -201,7 +200,7 @@
int textureWidth = iconBitmapSize;
int textureHeight = iconBitmapSize;
- final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
+ Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
Bitmap.Config.ARGB_8888);
final Canvas canvas = sCanvas;
canvas.setBitmap(bitmap);
@@ -218,29 +217,39 @@
icon.setBounds(sOldBounds);
canvas.setBitmap(null);
+ if (FeatureFlags.ADAPTIVE_ICON_SHADOW && Utilities.isAtLeastO()) {
+ try {
+ Class clazz = Class.forName("android.graphics.drawable.AdaptiveIconDrawable");
+ if (clazz.isAssignableFrom(icon.getClass())) {
+ bitmap = ShadowGenerator.getInstance(context).recreateIcon(bitmap);
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
return bitmap;
}
}
/**
- * If the platform is running O but the app is not providing MaskableIconDrawable, then
+ * If the platform is running O but the app is not providing AdaptiveIconDrawable, then
* shrink the legacy icon and set it as foreground. Use color drawable as background to
- * create MaskableIconDrawable.
+ * create AdaptiveIconDrawable.
*/
- static Drawable wrapToMaskableIconDrawable(Context context, Drawable drawable) {
+ static Drawable wrapToAdaptiveIconDrawable(Context context, Drawable drawable) {
if (!(FeatureFlags.LEGACY_ICON_TREATMENT && Utilities.isAtLeastO())) {
return drawable;
}
try {
- Class clazz = Class.forName("android.graphics.drawable.MaskableIconDrawable");
+ Class clazz = Class.forName("android.graphics.drawable.AdaptiveIconDrawable");
if (!clazz.isAssignableFrom(drawable.getClass())) {
- Drawable maskWrapper =
- context.getDrawable(R.drawable.mask_drawable_wrapper).mutate();
- ((FixedScaleDrawable) clazz.getMethod("getForeground").invoke(maskWrapper))
+ Drawable iconWrapper =
+ context.getDrawable(R.drawable.adaptive_icon_drawable_wrapper).mutate();
+ ((FixedScaleDrawable) clazz.getMethod("getForeground").invoke(iconWrapper))
.setDrawable(drawable);
- return maskWrapper;
+ return iconWrapper;
}
} catch (Exception e) {
return drawable;
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 3514a37..22ce098 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -217,6 +217,9 @@
if (Float.compare(finalProgress, mInternalStateProgress) == 0) {
return;
}
+ if (finalProgress < mInternalStateProgress) {
+ shouldAnimate = false;
+ }
if (!shouldAnimate || mRanFinishAnimation) {
setInternalProgress(finalProgress);
} else {
diff --git a/src/com/android/launcher3/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java
index 31276ec..6c603c9 100644
--- a/src/com/android/launcher3/graphics/ShadowGenerator.java
+++ b/src/com/android/launcher3/graphics/ShadowGenerator.java
@@ -83,6 +83,38 @@
return result;
}
+ public static Bitmap createCircleWithShadow(int circleColor, int diameter) {
+
+ float shadowRadius = diameter * 1f / 32;
+ float shadowYOffset = diameter * 1f / 16;
+
+ int radius = diameter / 2;
+
+ Canvas canvas = new Canvas();
+ Paint blurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ blurPaint.setMaskFilter(new BlurMaskFilter(shadowRadius, Blur.NORMAL));
+
+ int center = Math.round(radius + shadowRadius + shadowYOffset);
+ int size = center * 2;
+ Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888);
+ canvas.setBitmap(result);
+
+ // Draw ambient shadow, center aligned within size
+ blurPaint.setAlpha(AMBIENT_SHADOW_ALPHA);
+ canvas.drawCircle(center, center, radius, blurPaint);
+
+ // Draw key shadow, bottom aligned within size
+ blurPaint.setAlpha(KEY_SHADOW_ALPHA);
+ canvas.drawCircle(center, center + shadowYOffset, radius, blurPaint);
+
+ // Draw the circle
+ Paint drawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ drawPaint.setColor(circleColor);
+ canvas.drawCircle(center, center, radius, drawPaint);
+
+ return result;
+ }
+
public static ShadowGenerator getInstance(Context context) {
Preconditions.assertNonUiThread();
synchronized (LOCK) {
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 5f45c61..90e4531 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -18,6 +18,7 @@
import android.app.PendingIntent;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;
@@ -26,6 +27,7 @@
import com.android.launcher3.DropTarget;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -61,6 +63,19 @@
private static final boolean IS_VERBOSE =
ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
+ private static UserEventDispatcher sInstance;
+ private static final Object LOCK = new Object();
+
+ public static UserEventDispatcher get(Context context) {
+ synchronized (LOCK) {
+ if (sInstance == null) {
+ sInstance = Utilities.getOverrideObject(UserEventDispatcher.class,
+ context.getApplicationContext(), R.string.user_event_dispatcher_class);
+ }
+ return sInstance;
+ }
+ }
+
/**
* Implemented by containers to provide a container source for a given child.
*/
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index e50b912..221798b 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -27,7 +27,6 @@
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.LongArrayMap;
@@ -890,23 +889,6 @@
.apply();
}
- public static void logDeviceProfileIfChanged(InvariantDeviceProfile idp, Context context) {
- SharedPreferences prefs = Utilities.getPrefs(context);
- String gridSizeString = getPointString(idp.numColumns, idp.numRows);
-
- int oldHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons);
- String oldSize = prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString);
- if (gridSizeString.equals(oldSize) && idp.numHotseatIcons == oldHotseatCount) {
- // Skip if workspace and hotseat sizes have not changed.
- return;
- }
-
- FileLog.e(TAG, "Grid size changed" + gridSizeString);
- FileLog.e(TAG, " oldSize: " + oldSize + " , hotseat: " + oldHotseatCount);
- FileLog.e(TAG, " newSize: " + gridSizeString + " , hotseat: " + idp.numHotseatIcons);
- idp.dumpDisplayInfo(context);
- }
-
/**
* Migrates the workspace and hotseat in case their sizes changed.
* @return false if the migration failed.
diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
index 7c98362..278669b 100644
--- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java
+++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
@@ -63,7 +63,7 @@
for (String pkg : new HashSet<>(entry.getValue())) {
if (!launcherApps.isPackageEnabledForProfile(pkg, user)) {
- if (pmHelper.isAppOnSdcard(pkg)) {
+ if (pmHelper.isAppOnSdcard(pkg, user)) {
packagesUnavailable.add(pkg);
} else {
packagesRemoved.add(pkg);
diff --git a/src/com/android/launcher3/notification/NotificationFooterLayout.java b/src/com/android/launcher3/notification/NotificationFooterLayout.java
index 9686ae0..1eef743 100644
--- a/src/com/android/launcher3/notification/NotificationFooterLayout.java
+++ b/src/com/android/launcher3/notification/NotificationFooterLayout.java
@@ -21,19 +21,22 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
-import android.content.res.ColorStateList;
+import android.content.res.Resources;
import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import android.widget.TextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PropertyListBuilder;
-import com.android.launcher3.graphics.IconPalette;
+import com.android.launcher3.anim.PropertyResetListener;
import com.android.launcher3.popup.PopupContainerWithArrow;
import java.util.ArrayList;
@@ -41,10 +44,10 @@
import java.util.List;
/**
- * A {@link LinearLayout} that contains only icons of notifications.
- * If there are more than {@link #MAX_FOOTER_NOTIFICATIONS} icons, we add a "+x" overflow.
+ * A {@link FrameLayout} that contains only icons of notifications.
+ * If there are more than {@link #MAX_FOOTER_NOTIFICATIONS} icons, we add a "..." overflow.
*/
-public class NotificationFooterLayout extends LinearLayout {
+public class NotificationFooterLayout extends FrameLayout {
public interface IconAnimationEndListener {
void onIconAnimationEnd(NotificationInfo animatedNotification);
@@ -56,12 +59,12 @@
private final List<NotificationInfo> mNotifications = new ArrayList<>();
private final List<NotificationInfo> mOverflowNotifications = new ArrayList<>();
+ private final boolean mRtl;
- LinearLayout.LayoutParams mIconLayoutParams;
+ FrameLayout.LayoutParams mIconLayoutParams;
+ private View mOverflowEllipsis;
private LinearLayout mIconRow;
private int mBackgroundColor;
- private int mTextColor;
- private TextView mOverflowView;
public NotificationFooterLayout(Context context) {
this(context, null, 0);
@@ -74,26 +77,29 @@
public NotificationFooterLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- int size = getResources().getDimensionPixelSize(
- R.dimen.notification_footer_icon_size);
- int padding = getResources().getDimensionPixelSize(
- R.dimen.deep_shortcut_drawable_padding);
- mIconLayoutParams = new LayoutParams(size, size);
- mIconLayoutParams.setMarginStart(padding);
+ Resources res = getResources();
+ mRtl = Utilities.isRtl(res);
+
+ int iconSize = res.getDimensionPixelSize(R.dimen.notification_footer_icon_size);
+ mIconLayoutParams = new LayoutParams(iconSize, iconSize);
mIconLayoutParams.gravity = Gravity.CENTER_VERTICAL;
+ // Compute margin start for each icon such that the icons between the first one
+ // and the ellipsis are evenly spaced out.
+ int paddingEnd = res.getDimensionPixelSize(R.dimen.notification_footer_icon_row_padding);
+ int ellipsisSpace = res.getDimensionPixelSize(R.dimen.horizontal_ellipsis_offset)
+ + res.getDimensionPixelSize(R.dimen.horizontal_ellipsis_size);
+ int footerWidth = res.getDimensionPixelSize(R.dimen.bg_popup_item_width);
+ int availableIconRowSpace = footerWidth - paddingEnd - ellipsisSpace
+ - iconSize * MAX_FOOTER_NOTIFICATIONS;
+ mIconLayoutParams.setMarginStart(availableIconRowSpace / MAX_FOOTER_NOTIFICATIONS);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ mOverflowEllipsis = findViewById(R.id.overflow);
mIconRow = (LinearLayout) findViewById(R.id.icon_row);
- }
-
- public void applyColors(IconPalette iconPalette) {
- mBackgroundColor = iconPalette.backgroundColor;
- setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
- findViewById(R.id.divider).setBackgroundColor(iconPalette.secondaryColor);
- mTextColor = iconPalette.textColor;
+ mBackgroundColor = ((ColorDrawable) getBackground()).getColor();
}
/**
@@ -117,41 +123,32 @@
for (int i = 0; i < mNotifications.size(); i++) {
NotificationInfo info = mNotifications.get(i);
- addNotificationIconForInfo(info, false /* fromOverflow */);
+ addNotificationIconForInfo(info);
}
-
- if (!mOverflowNotifications.isEmpty()) {
- mOverflowView = new TextView(getContext());
- mOverflowView.setTextColor(mTextColor);
- updateOverflowText();
- mIconRow.addView(mOverflowView, mIconLayoutParams);
- }
+ updateOverflowEllipsisVisibility();
}
- private void addNotificationIconForInfo(NotificationInfo info, boolean fromOverflow) {
+ private void updateOverflowEllipsisVisibility() {
+ mOverflowEllipsis.setVisibility(mOverflowNotifications.isEmpty() ? GONE : VISIBLE);
+ }
+
+ /**
+ * Creates an icon for the given NotificationInfo, and adds it to the icon row.
+ * @return the icon view that was added
+ */
+ private View addNotificationIconForInfo(NotificationInfo info) {
View icon = new View(getContext());
icon.setBackground(info.getIconForBackground(getContext(), mBackgroundColor));
icon.setOnClickListener(info);
- int addIndex = mIconRow.getChildCount();
- if (fromOverflow) {
- // Add the notification before the overflow view.
- addIndex--;
- icon.setAlpha(0);
- icon.animate().alpha(1);
- }
icon.setTag(info);
- mIconRow.addView(icon, addIndex, mIconLayoutParams);
- }
-
- private void updateOverflowText() {
- mOverflowView.setText(getResources().getString(R.string.deep_notifications_overflow,
- mOverflowNotifications.size()));
+ mIconRow.addView(icon, 0, mIconLayoutParams);
+ return icon;
}
public void animateFirstNotificationTo(Rect toBounds,
final IconAnimationEndListener callback) {
AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
- final View firstNotification = mIconRow.getChildAt(0);
+ final View firstNotification = mIconRow.getChildAt(mIconRow.getChildCount() - 1);
Rect fromBounds = sTempRect;
firstNotification.getGlobalVisibleRect(fromBounds);
@@ -170,19 +167,24 @@
// Shift all notifications (not the overflow) over to fill the gap.
int gapWidth = mIconLayoutParams.width + mIconLayoutParams.getMarginStart();
- int numIcons = mIconRow.getChildCount()
- - (mOverflowNotifications.isEmpty() ? 0 : 1);
- for (int i = 1; i < numIcons; i++) {
+ if (mRtl) {
+ gapWidth = -gapWidth;
+ }
+ if (!mOverflowNotifications.isEmpty()) {
+ NotificationInfo notification = mOverflowNotifications.remove(0);
+ mNotifications.add(notification);
+ View iconFromOverflow = addNotificationIconForInfo(notification);
+ animation.play(ObjectAnimator.ofFloat(iconFromOverflow, ALPHA, 0, 1));
+ }
+ int numIcons = mIconRow.getChildCount() - 1; // All children besides the one leaving.
+ // We have to reset the translation X to 0 when the new main notification
+ // is removed from the footer.
+ PropertyResetListener<View, Float> propertyResetListener
+ = new PropertyResetListener<>(TRANSLATION_X, 0f);
+ for (int i = 0; i < numIcons; i++) {
final View child = mIconRow.getChildAt(i);
- Animator shiftChild = ObjectAnimator.ofFloat(child, TRANSLATION_X, -gapWidth);
- shiftChild.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // We have to set the translation X to 0 when the new main notification
- // is removed from the footer.
- child.setTranslationX(0);
- }
- });
+ Animator shiftChild = ObjectAnimator.ofFloat(child, TRANSLATION_X, gapWidth);
+ shiftChild.addListener(propertyResetListener);
animation.play(shiftChild);
}
animation.start();
@@ -191,32 +193,22 @@
private void removeViewFromIconRow(View child) {
mIconRow.removeView(child);
mNotifications.remove((NotificationInfo) child.getTag());
- if (!mOverflowNotifications.isEmpty()) {
- NotificationInfo notification = mOverflowNotifications.remove(0);
- mNotifications.add(notification);
- addNotificationIconForInfo(notification, true /* fromOverflow */);
- }
- if (mOverflowView != null) {
- if (mOverflowNotifications.isEmpty()) {
- mIconRow.removeView(mOverflowView);
- mOverflowView = null;
- } else {
- updateOverflowText();
- }
- }
+ updateOverflowEllipsisVisibility();
if (mIconRow.getChildCount() == 0) {
- // There are no more icons in the secondary view, so hide it.
+ // There are no more icons in the footer, so hide it.
PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(
Launcher.getLauncher(getContext()));
- int newHeight = getResources().getDimensionPixelSize(
- R.dimen.notification_footer_collapsed_height);
- AnimatorSet collapseSecondary = LauncherAnimUtils.createAnimatorSet();
- collapseSecondary.play(popup.animateTranslationYBy(getHeight() - newHeight, 0));
- collapseSecondary.play(LauncherAnimUtils.animateViewHeight(
- this, getHeight(), newHeight));
- collapseSecondary.setDuration(getResources().getInteger(
- R.integer.config_removeNotificationViewDuration));
- collapseSecondary.start();
+ if (popup != null) {
+ Animator collapseFooter = popup.reduceNotificationViewHeight(getHeight(),
+ getResources().getInteger(R.integer.config_removeNotificationViewDuration));
+ collapseFooter.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ ((ViewGroup) getParent()).removeView(NotificationFooterLayout.this);
+ }
+ });
+ collapseFooter.start();
+ }
}
}
@@ -230,16 +222,11 @@
overflowIterator.remove();
}
}
- TextView overflowView = null;
for (int i = mIconRow.getChildCount() - 1; i >= 0; i--) {
View child = mIconRow.getChildAt(i);
- if (child instanceof TextView) {
- overflowView = (TextView) child;
- } else {
- NotificationInfo childInfo = (NotificationInfo) child.getTag();
- if (!notifications.contains(childInfo.notificationKey)) {
- removeViewFromIconRow(child);
- }
+ NotificationInfo childInfo = (NotificationInfo) child.getTag();
+ if (!notifications.contains(childInfo.notificationKey)) {
+ removeViewFromIconRow(child);
}
}
}
diff --git a/src/com/android/launcher3/notification/NotificationHeaderView.java b/src/com/android/launcher3/notification/NotificationHeaderView.java
new file mode 100644
index 0000000..e70b489
--- /dev/null
+++ b/src/com/android/launcher3/notification/NotificationHeaderView.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.notification;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.launcher3.R;
+
+/**
+ * A {@link LinearLayout} that contains two text views: one for the notification count
+ * and one just to say "Notification" or "Notifications"
+ */
+public class NotificationHeaderView extends LinearLayout {
+
+ private TextView mNotificationCount;
+ private TextView mNotificationText;
+
+ public NotificationHeaderView(Context context) {
+ this(context, null, 0);
+ }
+
+ public NotificationHeaderView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public NotificationHeaderView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mNotificationCount = (TextView) findViewById(R.id.notification_count);
+ mNotificationText = (TextView) findViewById(R.id.notification_text);
+ }
+
+ public void update(int notificationCount) {
+ mNotificationCount.setText(String.valueOf(notificationCount));
+ mNotificationText.setText(getResources().getQuantityString(
+ R.plurals.notifications_header, notificationCount));
+ }
+}
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index 77a18c7..f6779b3 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -20,6 +20,7 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -27,6 +28,7 @@
import android.view.View;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.util.PackageUserKey;
@@ -36,15 +38,10 @@
* only be created when we need to show the notification contents on the UI; until then, a
* {@link com.android.launcher3.badge.BadgeInfo} with only the notification key should
* be passed around, and then this can be constructed using the StatusBarNotification from
- * {@link NotificationListener#getNotificationsForKeys(String[])}.
+ * {@link NotificationListener#getNotificationsForKeys(java.util.List)}.
*/
public class NotificationInfo implements View.OnClickListener {
- // TODO: use Notification constants directly.
- public static final int BADGE_ICON_NONE = 0;
- public static final int BADGE_ICON_SMALL = 1;
- public static final int BADGE_ICON_LARGE = 2;
-
public final PackageUserKey packageUserKey;
public final String notificationKey;
public final CharSequence title;
@@ -53,8 +50,8 @@
public final boolean autoCancel;
public final boolean dismissable;
- private final int mBadgeIcon;
- private final Drawable mIconDrawable;
+ private int mBadgeIcon;
+ private Drawable mIconDrawable;
private int mIconColor;
private boolean mIsIconLarge;
@@ -67,10 +64,10 @@
Notification notification = statusBarNotification.getNotification();
title = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
text = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
- mBadgeIcon = BADGE_ICON_LARGE; // TODO: get from the Notification
+ mBadgeIcon = notification.getBadgeIcon();
// Load the icon. Since it is backed by ashmem, we won't copy the entire bitmap
// into our process as long as we don't touch it and it exists in systemui.
- Icon icon = mBadgeIcon == BADGE_ICON_SMALL ? null : notification.getLargeIcon();
+ Icon icon = mBadgeIcon == Notification.BADGE_ICON_SMALL ? null : notification.getLargeIcon();
if (icon == null) {
// Use the small icon.
icon = notification.getSmallIcon();
@@ -82,6 +79,12 @@
mIconDrawable = icon.loadDrawable(context);
mIsIconLarge = true;
}
+ if (mIconDrawable == null) {
+ mIconDrawable = new BitmapDrawable(context.getResources(), LauncherAppState
+ .getInstance(context).getIconCache()
+ .getDefaultIcon(statusBarNotification.getUser()));
+ mBadgeIcon = Notification.BADGE_ICON_NONE;
+ }
intent = notification.contentIntent;
autoCancel = (notification.flags & Notification.FLAG_AUTO_CANCEL) != 0;
dismissable = (notification.flags & Notification.FLAG_ONGOING_EVENT) == 0;
@@ -125,7 +128,7 @@
public boolean shouldShowIconInBadge() {
// If the icon we're using for this notification matches what the Notification
// specified should show in the badge, then return true.
- return mIsIconLarge && mBadgeIcon == BADGE_ICON_LARGE
- || !mIsIconLarge && mBadgeIcon == BADGE_ICON_SMALL;
+ return mIsIconLarge && mBadgeIcon == Notification.BADGE_ICON_LARGE
+ || !mIsIconLarge && mBadgeIcon == Notification.BADGE_ICON_SMALL;
}
}
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index d58bef6..c6268e2 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -18,29 +18,22 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
import android.content.Context;
-import android.content.res.ColorStateList;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
-import android.widget.TextView;
import com.android.launcher3.ItemInfo;
-import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
-import com.android.launcher3.graphics.IconPalette;
+import com.android.launcher3.anim.PillHeightRevealOutlineProvider;
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
import com.android.launcher3.popup.PopupItemView;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import java.util.List;
-import static com.android.launcher3.LauncherAnimUtils.animateViewHeight;
-
/**
* A {@link FrameLayout} that contains a header, main view and a footer.
* The main view contains the icon and text (title + subtext) of the first notification.
@@ -51,8 +44,7 @@
private static final Rect sTempRect = new Rect();
- private TextView mHeader;
- private View mDivider;
+ private NotificationHeaderView mHeader;
private NotificationMainView mMainView;
private NotificationFooterLayout mFooter;
private SwipeHelper mSwipeHelper;
@@ -73,11 +65,33 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mHeader = (TextView) findViewById(R.id.header);
- mDivider = findViewById(R.id.divider);
+ mHeader = (NotificationHeaderView) findViewById(R.id.header);
mMainView = (NotificationMainView) findViewById(R.id.main_view);
mFooter = (NotificationFooterLayout) findViewById(R.id.footer);
mSwipeHelper = new SwipeHelper(SwipeHelper.X, mMainView, getContext());
+ mSwipeHelper.setDisableHardwareLayers(true);
+ }
+
+ public Animator animateHeightRemoval(int heightToRemove) {
+ final int newHeight = getHeight() - heightToRemove;
+ Animator heightAnimator = new PillHeightRevealOutlineProvider(mPillRect,
+ getBackgroundRadius(), newHeight).createRevealAnimator(this, true /* isReversed */);
+ heightAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (newHeight > 0) {
+ measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY));
+ initializeBackgroundClipping(true /* force */);
+ invalidate();
+ }
+ }
+ });
+ return heightAnimator;
+ }
+
+ public void updateHeader(int notificationCount) {
+ mHeader.update(notificationCount);
}
@Override
@@ -99,13 +113,6 @@
return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
}
- @Override
- protected ColorStateList getAttachedArrowColor() {
- // This NotificationView itself has a different color that is only
- // revealed when dismissing notifications.
- return mFooter.getBackgroundTintList();
- }
-
public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
if (notificationInfos.isEmpty()) {
return;
@@ -120,15 +127,6 @@
mFooter.commitNotificationInfos();
}
- public void applyColors(IconPalette iconPalette) {
- setBackgroundTintList(ColorStateList.valueOf(iconPalette.secondaryColor));
- mHeader.setBackgroundTintList(ColorStateList.valueOf(iconPalette.backgroundColor));
- mHeader.setTextColor(ColorStateList.valueOf(iconPalette.textColor));
- mDivider.setBackgroundColor(iconPalette.secondaryColor);
- mMainView.applyColors(iconPalette);
- mFooter.applyColors(iconPalette);
- }
-
public void trimNotifications(final List<String> notificationKeys) {
boolean dismissedMainNotification = !notificationKeys.contains(
mMainView.getNotificationInfo().notificationKey);
@@ -154,27 +152,6 @@
}
}
- public Animator createRemovalAnimation(int fullDuration) {
- AnimatorSet animation = new AnimatorSet();
- int mainHeight = mMainView.getMeasuredHeight();
- Animator removeMainView = animateViewHeight(mMainView, mainHeight, 0);
- removeMainView.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Remove the remaining views but take on their color instead of the darker one.
- setBackgroundTintList(mHeader.getBackgroundTintList());
- removeAllViews();
- }
- });
- Animator removeRest = LauncherAnimUtils.animateViewHeight(this, getHeight() - mainHeight, 0);
- removeMainView.setDuration(fullDuration / 2);
- removeRest.setDuration(fullDuration / 2);
- removeMainView.setInterpolator(new LinearInterpolator());
- removeRest.setInterpolator(new LinearInterpolator());
- animation.playSequentially(removeMainView, removeRest);
- return animation;
- }
-
@Override
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
LauncherLogProto.Target targetParent) {
diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java
new file mode 100644
index 0000000..bf7ae1a
--- /dev/null
+++ b/src/com/android/launcher3/notification/NotificationKeyData.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.notification;
+
+import android.app.Notification;
+import android.service.notification.StatusBarNotification;
+import android.support.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The key data associated with the notification, used to determine what to include
+ * in badges and dummy popup views before they are populated.
+ *
+ * @see NotificationInfo for the full data used when populating the dummy views.
+ */
+public class NotificationKeyData {
+ public final String notificationKey;
+ public final String shortcutId;
+ public int count;
+
+ private NotificationKeyData(String notificationKey, String shortcutId, int count) {
+ this.notificationKey = notificationKey;
+ this.shortcutId = shortcutId;
+ this.count = Math.max(1, count);
+ }
+
+ public static NotificationKeyData fromNotification(StatusBarNotification sbn) {
+ Notification notif = sbn.getNotification();
+ return new NotificationKeyData(sbn.getKey(), notif.getShortcutId(), notif.number);
+ }
+
+ public static List<String> extractKeysOnly(@NonNull List<NotificationKeyData> notificationKeys) {
+ List<String> keysOnly = new ArrayList<>(notificationKeys.size());
+ for (NotificationKeyData notificationKeyData : notificationKeys) {
+ keysOnly.add(notificationKeyData.notificationKey);
+ }
+ return keysOnly;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof NotificationKeyData)) {
+ return false;
+ }
+ // Only compare the keys.
+ return ((NotificationKeyData) obj).notificationKey.equals(notificationKey);
+ }
+}
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index a627d23..75a1b8a 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -17,6 +17,7 @@
package com.android.launcher3.notification;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -24,8 +25,10 @@
import android.service.notification.StatusBarNotification;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;
+import android.text.TextUtils;
import com.android.launcher3.LauncherModel;
+import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageUserKey;
@@ -55,6 +58,8 @@
private final Handler mWorkerHandler;
private final Handler mUiHandler;
+ private Ranking mTempRanking = new Ranking();
+
private Handler.Callback mWorkerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
@@ -89,8 +94,8 @@
break;
case MSG_NOTIFICATION_REMOVED:
if (sNotificationsChangedListener != null) {
- Pair<PackageUserKey, String> pair
- = (Pair<PackageUserKey, String>) message.obj;
+ Pair<PackageUserKey, NotificationKeyData> pair
+ = (Pair<PackageUserKey, NotificationKeyData>) message.obj;
sNotificationsChangedListener.onNotificationRemoved(pair.first, pair.second);
}
break;
@@ -160,29 +165,31 @@
*/
private class NotificationPostedMsg {
PackageUserKey packageUserKey;
- String notificationKey;
+ NotificationKeyData notificationKey;
boolean shouldBeFilteredOut;
NotificationPostedMsg(StatusBarNotification sbn) {
packageUserKey = PackageUserKey.fromNotification(sbn);
- notificationKey = sbn.getKey();
- shouldBeFilteredOut = shouldBeFilteredOut(sbn.getNotification());
+ notificationKey = NotificationKeyData.fromNotification(sbn);
+ shouldBeFilteredOut = shouldBeFilteredOut(sbn);
}
}
@Override
public void onNotificationRemoved(final StatusBarNotification sbn) {
super.onNotificationRemoved(sbn);
- Pair<PackageUserKey, String> packageUserKeyAndNotificationKey
- = new Pair<>(PackageUserKey.fromNotification(sbn), sbn.getKey());
+ Pair<PackageUserKey, NotificationKeyData> packageUserKeyAndNotificationKey
+ = new Pair<>(PackageUserKey.fromNotification(sbn),
+ NotificationKeyData.fromNotification(sbn));
mWorkerHandler.obtainMessage(MSG_NOTIFICATION_REMOVED, packageUserKeyAndNotificationKey)
.sendToTarget();
}
/** This makes a potentially expensive binder call and should be run on a background thread. */
- public List<StatusBarNotification> getNotificationsForKeys(String[] keys) {
+ public List<StatusBarNotification> getNotificationsForKeys(List<NotificationKeyData> keys) {
StatusBarNotification[] notifications = NotificationListener.this
- .getActiveNotifications(keys);
+ .getActiveNotifications(NotificationKeyData.extractKeysOnly(keys)
+ .toArray(new String[keys.size()]));
return notifications == null ? Collections.EMPTY_LIST : Arrays.asList(notifications);
}
@@ -190,14 +197,14 @@
* Filter out notifications that don't have an intent
* or are headers for grouped notifications.
*
- * TODO: use the system concept of a badged notification instead
+ * @see #shouldBeFilteredOut(StatusBarNotification)
*/
private List<StatusBarNotification> filterNotifications(
StatusBarNotification[] notifications) {
if (notifications == null) return null;
Set<Integer> removedNotifications = new HashSet<>();
for (int i = 0; i < notifications.length; i++) {
- if (shouldBeFilteredOut(notifications[i].getNotification())) {
+ if (shouldBeFilteredOut(notifications[i])) {
removedNotifications.add(i);
}
}
@@ -211,15 +218,32 @@
return filteredNotifications;
}
- private boolean shouldBeFilteredOut(Notification notification) {
+ private boolean shouldBeFilteredOut(StatusBarNotification sbn) {
+ if (Utilities.isAtLeastO()) {
+ getCurrentRanking().getRanking(sbn.getKey(), mTempRanking);
+ if (!mTempRanking.canShowBadge()) {
+ return true;
+ }
+ }
+ Notification notification = sbn.getNotification();
+ if (mTempRanking.getChannel().getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+ // Special filtering for the default, legacy "Miscellaneous" channel.
+ if ((notification.flags & Notification.FLAG_ONGOING_EVENT) != 0) {
+ return true;
+ }
+ }
boolean isGroupHeader = (notification.flags & Notification.FLAG_GROUP_SUMMARY) != 0;
- return (notification.contentIntent == null || isGroupHeader);
+ CharSequence title = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
+ CharSequence text = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
+ boolean missingTitleOrText = TextUtils.isEmpty(title) || TextUtils.isEmpty(text);
+ return (notification.contentIntent == null || isGroupHeader || missingTitleOrText);
}
public interface NotificationsChangedListener {
- void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey,
- boolean shouldBeFilteredOut);
- void onNotificationRemoved(PackageUserKey removedPackageUserKey, String notificationKey);
+ void onNotificationPosted(PackageUserKey postedPackageUserKey,
+ NotificationKeyData notificationKey, boolean shouldBeFilteredOut);
+ void onNotificationRemoved(PackageUserKey removedPackageUserKey,
+ NotificationKeyData notificationKey);
void onNotificationFullRefresh(List<StatusBarNotification> activeNotifications);
}
}
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index b342525..bb2dac0 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -16,38 +16,35 @@
package com.android.launcher3.notification;
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import android.widget.LinearLayout;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
-import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.util.Themes;
/**
- * A {@link LinearLayout} that contains a single notification, e.g. icon + title + text.
+ * A {@link android.widget.FrameLayout} that contains a single notification,
+ * e.g. icon + title + text.
*/
-public class NotificationMainView extends LinearLayout implements SwipeHelper.Callback {
-
- private final ArgbEvaluator mArgbEvaluator = new ArgbEvaluator();
+public class NotificationMainView extends FrameLayout implements SwipeHelper.Callback {
private NotificationInfo mNotificationInfo;
+ private ViewGroup mTextAndBackground;
+ private int mBackgroundColor;
private TextView mTitleView;
private TextView mTextView;
- private IconPalette mIconPalette;
- private ColorDrawable mColorBackground;
public NotificationMainView(Context context) {
this(context, null, 0);
@@ -65,14 +62,15 @@
protected void onFinishInflate() {
super.onFinishInflate();
- mTitleView = (TextView) findViewById(R.id.title);
- mTextView = (TextView) findViewById(R.id.text);
- }
-
- public void applyColors(IconPalette iconPalette) {
- mColorBackground = new ColorDrawable(iconPalette.backgroundColor);
- setBackground(mColorBackground);
- mIconPalette = iconPalette;
+ mTextAndBackground = (ViewGroup) findViewById(R.id.text_and_background);
+ ColorDrawable colorBackground = (ColorDrawable) mTextAndBackground.getBackground();
+ mBackgroundColor = colorBackground.getColor();
+ RippleDrawable rippleBackground = new RippleDrawable(ColorStateList.valueOf(
+ Themes.getAttrColor(getContext(), android.R.attr.colorControlHighlight)),
+ colorBackground, null);
+ mTextAndBackground.setBackground(rippleBackground);
+ mTitleView = (TextView) mTextAndBackground.findViewById(R.id.title);
+ mTextView = (TextView) mTextAndBackground.findViewById(R.id.text);
}
public void applyNotificationInfo(NotificationInfo mainNotification, View iconView) {
@@ -84,30 +82,18 @@
*/
public void applyNotificationInfo(NotificationInfo mainNotification, View iconView,
boolean animate) {
- if (animate) {
- mTitleView.setAlpha(0);
- mTextView.setAlpha(0);
- mColorBackground.setColor(mIconPalette.secondaryColor);
- }
mNotificationInfo = mainNotification;
mTitleView.setText(mNotificationInfo.title);
mTextView.setText(mNotificationInfo.text);
- iconView.setBackground(mNotificationInfo.getIconForBackground(
- getContext(), mIconPalette.backgroundColor));
+ iconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
+ mBackgroundColor));
setOnClickListener(mNotificationInfo);
setTranslationX(0);
// Add a dummy ItemInfo so that logging populates the correct container and item types
// instead of DEFAULT_CONTAINERTYPE and DEFAULT_ITEMTYPE, respectively.
setTag(new ItemInfo());
if (animate) {
- AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
- Animator textFade = ObjectAnimator.ofFloat(mTextView, View.ALPHA, 1);
- Animator titleFade = ObjectAnimator.ofFloat(mTitleView, View.ALPHA, 1);
- ValueAnimator colorChange = ObjectAnimator.ofObject(mColorBackground, "color",
- mArgbEvaluator, mIconPalette.secondaryColor, mIconPalette.backgroundColor);
- animation.playTogether(textFade, titleFade, colorChange);
- animation.setDuration(150);
- animation.start();
+ ObjectAnimator.ofFloat(mTextAndBackground, ALPHA, 0, 1).setDuration(150).start();
}
}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index d34727c..b2018b9 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -27,14 +27,12 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
-import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
-import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -60,19 +58,19 @@
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
import com.android.launcher3.anim.PropertyListBuilder;
+import com.android.launcher3.anim.PropertyResetListener;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.dragndrop.DragView;
-import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.graphics.TriangleShape;
import com.android.launcher3.notification.NotificationItemView;
+import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.shortcuts.DeepShortcutView;
-import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
+import com.android.launcher3.shortcuts.ShortcutsItemView;
import com.android.launcher3.util.PackageUserKey;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -84,18 +82,17 @@
* A container for shortcuts to deep links within apps.
*/
@TargetApi(Build.VERSION_CODES.N)
-public class PopupContainerWithArrow extends AbstractFloatingView
- implements View.OnLongClickListener, View.OnTouchListener, DragSource,
+public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource,
DragController.DragListener {
- private final Point mIconShift = new Point();
- private final Point mIconLastTouchPos = new Point();
-
protected final Launcher mLauncher;
private final int mStartDragThreshold;
private LauncherAccessibilityDelegate mAccessibilityDelegate;
private final boolean mIsRtl;
+ public ShortcutsItemView mShortcutsItemView;
+ private NotificationItemView mNotificationItemView;
+
protected BubbleTextView mOriginalIcon;
private final Rect mTempRect = new Rect();
private PointF mInterceptTouchDown = new PointF();
@@ -142,9 +139,9 @@
}
ItemInfo itemInfo = (ItemInfo) icon.getTag();
List<String> shortcutIds = launcher.getPopupDataProvider().getShortcutIdsForItem(itemInfo);
- String[] notificationKeys = launcher.getPopupDataProvider()
+ List<NotificationKeyData> notificationKeys = launcher.getPopupDataProvider()
.getNotificationKeysForItem(itemInfo);
- if (shortcutIds.size() > 0 || notificationKeys.length > 0) {
+ if (shortcutIds.size() > 0 || notificationKeys.size() > 0) {
final PopupContainerWithArrow container =
(PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
R.layout.popup_container, launcher.getDragLayer(), false);
@@ -157,7 +154,7 @@
}
public void populateAndShow(final BubbleTextView originalIcon, final List<String> shortcutIds,
- final String[] notificationKeys) {
+ final List<NotificationKeyData> notificationKeys) {
final Resources resources = getResources();
final int arrowWidth = resources.getDimensionPixelSize(R.dimen.deep_shortcuts_arrow_width);
final int arrowHeight = resources.getDimensionPixelSize(R.dimen.deep_shortcuts_arrow_height);
@@ -169,7 +166,7 @@
// Add dummy views first, and populate with real info when ready.
PopupPopulator.Item[] itemsToPopulate = PopupPopulator
.getItemsToPopulate(shortcutIds, notificationKeys);
- addDummyViews(originalIcon, itemsToPopulate, notificationKeys.length > 1);
+ addDummyViews(originalIcon, itemsToPopulate, notificationKeys.size() > 1);
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -177,39 +174,29 @@
boolean reverseOrder = mIsAboveIcon;
if (reverseOrder) {
removeAllViews();
+ mNotificationItemView = null;
+ mShortcutsItemView = null;
itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate);
- addDummyViews(originalIcon, itemsToPopulate, notificationKeys.length > 1);
+ addDummyViews(originalIcon, itemsToPopulate, notificationKeys.size() > 1);
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
}
- List<DeepShortcutView> shortcutViews = new ArrayList<>();
- NotificationItemView notificationView = null;
- for (int i = 0; i < getChildCount(); i++) {
- View item = getChildAt(i);
- switch (itemsToPopulate[i]) {
- case SHORTCUT:
- if (reverseOrder) {
- shortcutViews.add(0, (DeepShortcutView) item);
- } else {
- shortcutViews.add((DeepShortcutView) item);
- }
- break;
- case NOTIFICATION:
- notificationView = (NotificationItemView) item;
- IconPalette iconPalette = originalIcon.getIconPalette();
- notificationView.applyColors(iconPalette);
- break;
- }
+ ItemInfo originalItemInfo = (ItemInfo) originalIcon.getTag();
+ List<DeepShortcutView> shortcutViews = mShortcutsItemView == null
+ ? Collections.EMPTY_LIST
+ : mShortcutsItemView.getDeepShortcutViews(reverseOrder);
+ if (mNotificationItemView != null) {
+ BadgeInfo badgeInfo = mLauncher.getPopupDataProvider()
+ .getBadgeInfoForItem(originalItemInfo);
+ updateNotificationHeader(badgeInfo);
}
// Add the arrow.
mArrow = addArrowView(arrowHorizontalOffset, arrowVerticalOffset, arrowWidth, arrowHeight);
mArrow.setPivotX(arrowWidth / 2);
mArrow.setPivotY(mIsAboveIcon ? 0 : arrowHeight);
- PopupItemView firstItem = getItemViewAt(mIsAboveIcon ? getItemCount() - 1 : 0);
- mArrow.setBackgroundTintList(firstItem.getAttachedArrowColor());
animateOpen();
@@ -220,30 +207,47 @@
// Load the shortcuts on a background thread and update the container as it animates.
final Looper workerLooper = LauncherModel.getWorkerLooper();
new Handler(workerLooper).postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
- mLauncher, (ItemInfo) originalIcon.getTag(), new Handler(Looper.getMainLooper()),
- this, shortcutIds, shortcutViews, notificationKeys, notificationView));
+ mLauncher, originalItemInfo, new Handler(Looper.getMainLooper()),
+ this, shortcutIds, shortcutViews, notificationKeys, mNotificationItemView));
}
private void addDummyViews(BubbleTextView originalIcon,
- PopupPopulator.Item[] itemsToPopulate, boolean secondaryNotificationViewHasIcons) {
+ PopupPopulator.Item[] itemTypesToPopulate, boolean notificationFooterHasIcons) {
final Resources res = getResources();
- final int spacing = res.getDimensionPixelSize(R.dimen.deep_shortcuts_spacing);
+ final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing);
final LayoutInflater inflater = mLauncher.getLayoutInflater();
- int numItems = itemsToPopulate.length;
+ int numItems = itemTypesToPopulate.length;
for (int i = 0; i < numItems; i++) {
- final PopupItemView item = (PopupItemView) inflater.inflate(
- itemsToPopulate[i].layoutId, this, false);
- if (itemsToPopulate[i] == PopupPopulator.Item.NOTIFICATION) {
- int secondaryHeight = secondaryNotificationViewHasIcons ?
- res.getDimensionPixelSize(R.dimen.notification_footer_height) :
- res.getDimensionPixelSize(R.dimen.notification_footer_collapsed_height);
- item.findViewById(R.id.footer).getLayoutParams().height = secondaryHeight;
+ PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i];
+ final View item = inflater.inflate(itemTypeToPopulate.layoutId, this, false);
+
+ if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
+ mNotificationItemView = (NotificationItemView) item;
+ int footerHeight = notificationFooterHasIcons ?
+ res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
+ item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
}
- if (i < numItems - 1) {
- ((LayoutParams) item.getLayoutParams()).bottomMargin = spacing;
- }
+
+ boolean itemIsFollowedByDifferentType = i < numItems - 1
+ && itemTypesToPopulate[i + 1] != itemTypeToPopulate;
+
item.setAccessibilityDelegate(mAccessibilityDelegate);
- addView(item);
+ if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) {
+ if (mShortcutsItemView == null) {
+ mShortcutsItemView = (ShortcutsItemView) inflater.inflate(
+ R.layout.shortcuts_item, this, false);
+ addView(mShortcutsItemView);
+ }
+ mShortcutsItemView.addDeepShortcutView((DeepShortcutView) item);
+ if (itemIsFollowedByDifferentType) {
+ ((LayoutParams) mShortcutsItemView.getLayoutParams()).bottomMargin = spacing;
+ }
+ } else {
+ addView(item);
+ if (itemIsFollowedByDifferentType) {
+ ((LayoutParams) item.getLayoutParams()).bottomMargin = spacing;
+ }
+ }
}
// TODO: update this, since not all items are shortcuts
setContentDescription(getContext().getString(R.string.shortcuts_menu_description,
@@ -535,48 +539,26 @@
return true;
}
- @Override
- public boolean onTouch(View v, MotionEvent ev) {
- // Touched a shortcut, update where it was touched so we can drag from there on long click.
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_MOVE:
- mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
- break;
+ /**
+ * Updates the notification header to reflect the badge info. Since this can be called
+ * for any badge info (not necessarily the one associated with this app), we first
+ * check that the ItemInfo matches the one of this popup.
+ */
+ public void updateNotificationHeader(BadgeInfo badgeInfo, ItemInfo originalItemInfo) {
+ if (originalItemInfo != mOriginalIcon.getTag()) {
+ return;
}
- return false;
+ updateNotificationHeader(badgeInfo);
}
- public boolean onLongClick(View v) {
- // Return early if this is not initiated from a touch or not the correct view
- if (!v.isInTouchMode() || !(v.getParent() instanceof DeepShortcutView)) return false;
- // Return early if global dragging is not enabled
- if (!mLauncher.isDraggingEnabled()) return false;
- // Return early if an item is already being dragged (e.g. when long-pressing two shortcuts)
- if (mLauncher.getDragController().isDragging()) return false;
-
- // Long clicked on a shortcut.
- mDeferContainerRemoval = true;
- DeepShortcutView sv = (DeepShortcutView) v.getParent();
- sv.setWillDrawIcon(false);
-
- // Move the icon to align with the center-top of the touch point
- mIconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
- mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx;
-
- DragView dv = mLauncher.getWorkspace().beginDragShared(
- sv.getBubbleText(), this, sv.getFinalInfo(),
- new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions());
- dv.animateShift(-mIconShift.x, -mIconShift.y);
-
- // TODO: support dragging from within folder without having to close it
- AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_FOLDER);
- return false;
+ private void updateNotificationHeader(BadgeInfo badgeInfo) {
+ if (mNotificationItemView != null && badgeInfo != null) {
+ mNotificationItemView.updateHeader(badgeInfo.getNotificationCount());
+ }
}
public void trimNotifications(Map<PackageUserKey, BadgeInfo> updatedBadges) {
- final NotificationItemView notificationView = (NotificationItemView) findViewById(R.id.notification_view);
- if (notificationView == null) {
+ if (mNotificationItemView == null) {
return;
}
ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
@@ -585,12 +567,11 @@
AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
final int duration = getResources().getInteger(
R.integer.config_removeNotificationViewDuration);
- final int spacing = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_spacing);
- removeNotification.play(animateTranslationYBy(notificationView.getHeight() + spacing,
- duration));
- Animator reduceHeight = notificationView.createRemovalAnimation(duration);
+ final int spacing = getResources().getDimensionPixelSize(R.dimen.popup_items_spacing);
+ removeNotification.play(reduceNotificationViewHeight(
+ mNotificationItemView.getHeight() + spacing, duration));
final View removeMarginView = mIsAboveIcon ? getItemViewAt(getItemCount() - 2)
- : notificationView;
+ : mNotificationItemView;
if (removeMarginView != null) {
ValueAnimator removeMargin = ValueAnimator.ofFloat(1, 0).setDuration(duration);
removeMargin.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -602,19 +583,17 @@
});
removeNotification.play(removeMargin);
}
- removeNotification.play(reduceHeight);
- Animator fade = ObjectAnimator.ofFloat(notificationView, ALPHA, 0)
+ Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
.setDuration(duration);
fade.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- removeView(notificationView);
+ removeView(mNotificationItemView);
+ mNotificationItemView = null;
if (getItemCount() == 0) {
close(false);
return;
}
- View firstItem = getItemViewAt(mIsAboveIcon ? getItemCount() - 1 : 0);
- mArrow.setBackgroundTintList(firstItem.getBackgroundTintList());
}
});
removeNotification.play(fade);
@@ -628,24 +607,47 @@
removeNotification.start();
return;
}
- notificationView.trimNotifications(badgeInfo.getNotificationKeys());
+ mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly(
+ badgeInfo.getNotificationKeys()));
}
private ObjectAnimator createArrowScaleAnim(float scale) {
return LauncherAnimUtils.ofPropertyValuesHolder(
mArrow, new PropertyListBuilder().scale(scale).build());
}
+
/**
- * Animates the translationY of this container if it is open above the icon.
- * If it is below the icon, the container already shifts up when the height
- * of a child (e.g. NotificationView) changes, so the translation isn't necessary.
+ * Animates the height of the notification item and the translationY of other items accordingly.
*/
- public @Nullable Animator animateTranslationYBy(int translationY, int duration) {
- if (mIsAboveIcon) {
- return ObjectAnimator.ofFloat(this, TRANSLATION_Y, getTranslationY() + translationY)
- .setDuration(duration);
+ public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
+ final int translateYBy = mIsAboveIcon ? heightToRemove : -heightToRemove;
+ AnimatorSet animatorSet = LauncherAnimUtils.createAnimatorSet();
+ animatorSet.play(mNotificationItemView.animateHeightRemoval(heightToRemove));
+ PropertyResetListener<View, Float> resetTranslationYListener
+ = new PropertyResetListener<>(TRANSLATION_Y, 0f);
+ for (int i = 0; i < getItemCount(); i++) {
+ final PopupItemView itemView = getItemViewAt(i);
+ if (!mIsAboveIcon && itemView == mNotificationItemView) {
+ // The notification view is already in the right place when container is below icon.
+ continue;
+ }
+ ValueAnimator translateItem = ObjectAnimator.ofFloat(itemView, TRANSLATION_Y,
+ itemView.getTranslationY() + translateYBy).setDuration(duration);
+ translateItem.addListener(resetTranslationYListener);
+ animatorSet.play(translateItem);
}
- return null;
+ if (mIsAboveIcon) {
+ // All the items, including the notification item, translated down, but the
+ // container itself did not. This means the items would jump back to their
+ // original translation unless we update the container's translationY here.
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ setTranslationY(getTranslationY() + translateYBy);
+ }
+ });
+ }
+ return animatorSet;
}
@Override
@@ -677,6 +679,7 @@
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
// Either the original icon or one of the shortcuts was dragged.
// Hide the container, but don't remove it yet because that interferes with touch events.
+ mDeferContainerRemoval = true;
animateClose();
}
@@ -698,7 +701,6 @@
@Override
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
target.itemType = ItemType.DEEPSHORTCUT;
- target.rank = info.rank;
targetParent.containerType = ContainerType.DEEPSHORTCUTS;
}
@@ -740,38 +742,17 @@
for (int i = firstOpenItemIndex; i < firstOpenItemIndex + numOpenShortcuts; i++) {
final PopupItemView view = getItemViewAt(i);
Animator anim;
- if (view.willDrawIcon()) {
- anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration);
- int animationIndex = mIsAboveIcon ? i - firstOpenItemIndex
- : numOpenShortcuts - i - 1;
- anim.setStartDelay(stagger * animationIndex);
+ anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration);
+ int animationIndex = mIsAboveIcon ? i - firstOpenItemIndex
+ : numOpenShortcuts - i - 1;
+ anim.setStartDelay(stagger * animationIndex);
- Animator fadeAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
- // Don't start fading until the arrow is gone.
- fadeAnim.setStartDelay(stagger * animationIndex + arrowScaleDuration);
- fadeAnim.setDuration(duration - arrowScaleDuration);
- fadeAnim.setInterpolator(fadeInterpolator);
- shortcutAnims.play(fadeAnim);
- } else {
- // The view is being dragged. Animate it such that it collapses with the drag view
- anim = view.collapseToIcon();
- anim.setDuration(DragView.VIEW_ZOOM_DURATION);
-
- // Scale and translate the view to follow the drag view.
- Point iconCenter = view.getIconCenter();
- view.setPivotX(iconCenter.x);
- view.setPivotY(iconCenter.y);
-
- float scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / view.getHeight();
- Animator anim2 = LauncherAnimUtils.ofPropertyValuesHolder(view,
- new PropertyListBuilder()
- .scale(scale)
- .translationX(mIconShift.x)
- .translationY(mIconShift.y)
- .build())
- .setDuration(DragView.VIEW_ZOOM_DURATION);
- shortcutAnims.play(anim2);
- }
+ Animator fadeAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
+ // Don't start fading until the arrow is gone.
+ fadeAnim.setStartDelay(stagger * animationIndex + arrowScaleDuration);
+ fadeAnim.setDuration(duration - arrowScaleDuration);
+ fadeAnim.setInterpolator(fadeInterpolator);
+ shortcutAnims.play(fadeAnim);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index ee2930f..9c4faed 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.service.notification.StatusBarNotification;
+import android.support.annotation.NonNull;
import android.util.Log;
import com.android.launcher3.ItemInfo;
@@ -25,6 +26,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.notification.NotificationInfo;
+import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.util.ComponentKey;
@@ -58,30 +60,34 @@
}
@Override
- public void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey,
- boolean shouldBeFilteredOut) {
+ public void onNotificationPosted(PackageUserKey postedPackageUserKey,
+ NotificationKeyData notificationKey, boolean shouldBeFilteredOut) {
BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(postedPackageUserKey);
- boolean notificationWasAddedOrRemoved; // As opposed to updated.
+ boolean badgeShouldBeRefreshed;
if (badgeInfo == null) {
if (!shouldBeFilteredOut) {
BadgeInfo newBadgeInfo = new BadgeInfo(postedPackageUserKey);
- newBadgeInfo.addNotificationKeyIfNotExists(notificationKey);
+ newBadgeInfo.addOrUpdateNotificationKey(notificationKey);
mPackageUserToBadgeInfos.put(postedPackageUserKey, newBadgeInfo);
- notificationWasAddedOrRemoved = true;
+ badgeShouldBeRefreshed = true;
} else {
- notificationWasAddedOrRemoved = false;
+ badgeShouldBeRefreshed = false;
}
} else {
- notificationWasAddedOrRemoved = shouldBeFilteredOut
+ badgeShouldBeRefreshed = shouldBeFilteredOut
? badgeInfo.removeNotificationKey(notificationKey)
- : badgeInfo.addNotificationKeyIfNotExists(notificationKey);
+ : badgeInfo.addOrUpdateNotificationKey(notificationKey);
+ if (badgeInfo.getNotificationCount() == 0) {
+ mPackageUserToBadgeInfos.remove(postedPackageUserKey);
+ }
}
updateLauncherIconBadges(Utilities.singletonHashSet(postedPackageUserKey),
- notificationWasAddedOrRemoved);
+ badgeShouldBeRefreshed);
}
@Override
- public void onNotificationRemoved(PackageUserKey removedPackageUserKey, String notificationKey) {
+ public void onNotificationRemoved(PackageUserKey removedPackageUserKey,
+ NotificationKeyData notificationKey) {
BadgeInfo oldBadgeInfo = mPackageUserToBadgeInfos.get(removedPackageUserKey);
if (oldBadgeInfo != null && oldBadgeInfo.removeNotificationKey(notificationKey)) {
if (oldBadgeInfo.getNotificationCount() == 0) {
@@ -109,7 +115,8 @@
badgeInfo = new BadgeInfo(packageUserKey);
mPackageUserToBadgeInfos.put(packageUserKey, badgeInfo);
}
- badgeInfo.addNotificationKeyIfNotExists(notification.getKey());
+ badgeInfo.addOrUpdateNotificationKey(NotificationKeyData
+ .fromNotification(notification));
}
// Add and remove from updatedBadges so it contains the PackageUserKeys of updated badges.
@@ -143,17 +150,17 @@
* Updates the icons on launcher (workspace, folders, all apps) to refresh their badges.
* @param updatedBadges The packages whose badges should be refreshed (either a notification was
* added or removed, or the badge should show the notification icon).
- * @param addedOrRemoved An optional parameter that will allow us to only refresh badges that
- * updated (not added/removed) that have icons. If a badge updated
- * but it doesn't have an icon, then the badge number doesn't change.
+ * @param shouldRefresh An optional parameter that will allow us to only refresh badges that
+ * have actually changed. If a notification updated its content but not
+ * its count or icon, then the badge doesn't change.
*/
private void updateLauncherIconBadges(Set<PackageUserKey> updatedBadges,
- boolean addedOrRemoved) {
+ boolean shouldRefresh) {
Iterator<PackageUserKey> iterator = updatedBadges.iterator();
while (iterator.hasNext()) {
BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(iterator.next());
- if (badgeInfo != null && !updateBadgeIcon(badgeInfo) && !addedOrRemoved) {
- // The notification icon isn't used, and the badge wasn't added or removed
+ if (badgeInfo != null && !updateBadgeIcon(badgeInfo) && !shouldRefresh) {
+ // The notification icon isn't used, and the badge hasn't changed
// so there is no update to be made.
iterator.remove();
}
@@ -174,8 +181,9 @@
NotificationInfo notificationInfo = null;
NotificationListener notificationListener = NotificationListener.getInstanceIfConnected();
if (notificationListener != null && badgeInfo.getNotificationKeys().size() == 1) {
+ String onlyNotificationKey = badgeInfo.getNotificationKeys().get(0).notificationKey;
StatusBarNotification[] activeNotifications = notificationListener
- .getActiveNotifications(new String[] {badgeInfo.getNotificationKeys().get(0)});
+ .getActiveNotifications(new String[] {onlyNotificationKey});
if (activeNotifications.length == 1) {
notificationInfo = new NotificationInfo(mLauncher, activeNotifications[0]);
if (!notificationInfo.shouldShowIconInBadge()) {
@@ -213,15 +221,14 @@
return mPackageUserToBadgeInfos.get(PackageUserKey.fromItemInfo(info));
}
- public String[] getNotificationKeysForItem(ItemInfo info) {
+ public @NonNull List<NotificationKeyData> getNotificationKeysForItem(ItemInfo info) {
BadgeInfo badgeInfo = getBadgeInfoForItem(info);
- if (badgeInfo == null) { return new String[0]; }
- List<String> notificationKeys = badgeInfo.getNotificationKeys();
- return notificationKeys.toArray(new String[notificationKeys.size()]);
+ return badgeInfo == null ? Collections.EMPTY_LIST : badgeInfo.getNotificationKeys();
}
/** This makes a potentially expensive binder call and should be run on a background thread. */
- public List<StatusBarNotification> getStatusBarNotificationsForKeys(String[] notificationKeys) {
+ public @NonNull List<StatusBarNotification> getStatusBarNotificationsForKeys(
+ List<NotificationKeyData> notificationKeys) {
NotificationListener notificationListener = NotificationListener.getInstanceIfConnected();
return notificationListener == null ? Collections.EMPTY_LIST
: notificationListener.getNotificationsForKeys(notificationKeys);
diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java
index 6af6e7d..b839d99 100644
--- a/src/com/android/launcher3/popup/PopupItemView.java
+++ b/src/com/android/launcher3/popup/PopupItemView.java
@@ -20,9 +20,15 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
-import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
+import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
@@ -31,7 +37,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.PillRevealOutlineProvider;
-import com.android.launcher3.util.PillWidthRevealOutlineProvider;
/**
* An abstract {@link FrameLayout} that supports animating an item's content
@@ -42,11 +47,14 @@
protected static final Point sTempPoint = new Point();
- private final Rect mPillRect;
+ protected final Rect mPillRect;
private float mOpenAnimationProgress;
protected View mIconView;
+ private final Paint mBackgroundClipPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG |
+ Paint.FILTER_BITMAP_FLAG);
+
public PopupItemView(Context context) {
this(context, null, 0);
}
@@ -73,12 +81,31 @@
mPillRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
}
- protected ColorStateList getAttachedArrowColor() {
- return getBackgroundTintList();
+ protected void initializeBackgroundClipping(boolean force) {
+ if (force || mBackgroundClipPaint.getShader() == null) {
+ mBackgroundClipPaint.setXfermode(null);
+ mBackgroundClipPaint.setShader(null);
+ Bitmap backgroundBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
+ Bitmap.Config.ALPHA_8);
+ Canvas canvas = new Canvas();
+ canvas.setBitmap(backgroundBitmap);
+ canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
+ getBackgroundRadius(), getBackgroundRadius(), mBackgroundClipPaint);
+ Shader backgroundClipShader = new BitmapShader(backgroundBitmap,
+ Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ mBackgroundClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
+ mBackgroundClipPaint.setShader(backgroundClipShader);
+ }
}
- public boolean willDrawIcon() {
- return true;
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ initializeBackgroundClipping(false /* force */);
+ int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
+ Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+ super.dispatchDraw(canvas);
+ canvas.drawPaint(mBackgroundClipPaint);
+ canvas.restoreToCount(saveCount);
}
/**
@@ -126,17 +153,6 @@
}
/**
- * Creates an animator which clips the container to form a circle around the icon.
- */
- public Animator collapseToIcon() {
- int halfHeight = getMeasuredHeight() / 2;
- int iconCenterX = getIconCenter().x;
- return new PillWidthRevealOutlineProvider(mPillRect,
- iconCenterX - halfHeight, iconCenterX + halfHeight)
- .createRevealAnimator(this, true);
- }
-
- /**
* Returns the position of the center of the icon relative to the container.
*/
public Point getIconCenter() {
@@ -147,6 +163,10 @@
return sTempPoint;
}
+ protected float getBackgroundRadius() {
+ return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
+ }
+
/**
* Extension of {@link PillRevealOutlineProvider} which scales the icon based on the height.
*/
@@ -161,10 +181,9 @@
private final boolean mPivotLeft;
private final float mTranslateX;
- public ZoomRevealOutlineProvider(int x, int y, Rect pillRect,
- View translateView, View zoomView, boolean isContainerAboveIcon, boolean pivotLeft) {
- super(x, y, pillRect, zoomView.getResources().getDimensionPixelSize(
- R.dimen.bg_pill_radius));
+ public ZoomRevealOutlineProvider(int x, int y, Rect pillRect, PopupItemView translateView,
+ View zoomView, boolean isContainerAboveIcon, boolean pivotLeft) {
+ super(x, y, pillRect, translateView.getBackgroundRadius());
mTranslateView = translateView;
mZoomView = zoomView;
mFullHeight = pillRect.height();
@@ -179,8 +198,10 @@
public void setProgress(float progress) {
super.setProgress(progress);
- mZoomView.setScaleX(progress);
- mZoomView.setScaleY(progress);
+ if (mZoomView != null) {
+ mZoomView.setScaleX(progress);
+ mZoomView.setScaleY(progress);
+ }
float height = mOutline.height();
mTranslateView.setTranslationY(mTranslateYMultiplier * (mFullHeight - height));
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index d2814ee..9b2141f 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -20,15 +20,18 @@
import android.os.Handler;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.notification.NotificationInfo;
import com.android.launcher3.notification.NotificationItemView;
-import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@@ -36,6 +39,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
/**
@@ -58,8 +62,9 @@
}
}
- public static Item[] getItemsToPopulate(List<String> shortcutIds, String[] notificationKeys) {
- boolean hasNotifications = notificationKeys.length > 0;
+ public static @NonNull Item[] getItemsToPopulate(@NonNull List<String> shortcutIds,
+ @NonNull List<NotificationKeyData> notificationKeys) {
+ boolean hasNotifications = notificationKeys.size() > 0;
int numNotificationItems = hasNotifications ? 1 : 0;
int numItems = Math.min(MAX_ITEMS, shortcutIds.size() + numNotificationItems);
Item[] items = new Item[numItems];
@@ -105,10 +110,22 @@
* We want the filter to include both static and dynamic shortcuts, so we always
* include NUM_DYNAMIC dynamic shortcuts, if at least that many are present.
*
+ * @param shortcutIdToRemoveFirst An id that should be filtered out first, if any.
* @return a subset of shortcuts, in sorted order, with size <= MAX_ITEMS.
*/
public static List<ShortcutInfoCompat> sortAndFilterShortcuts(
- List<ShortcutInfoCompat> shortcuts) {
+ List<ShortcutInfoCompat> shortcuts, @Nullable String shortcutIdToRemoveFirst) {
+ // Remove up to one specific shortcut before sorting and doing somewhat fancy filtering.
+ if (shortcutIdToRemoveFirst != null) {
+ Iterator<ShortcutInfoCompat> shortcutIterator = shortcuts.iterator();
+ while (shortcutIterator.hasNext()) {
+ if (shortcutIterator.next().getId().equals(shortcutIdToRemoveFirst)) {
+ shortcutIterator.remove();
+ break;
+ }
+ }
+ }
+
Collections.sort(shortcuts, SHORTCUT_RANK_COMPARATOR);
if (shortcuts.size() <= MAX_ITEMS) {
return shortcuts;
@@ -145,7 +162,8 @@
public static Runnable createUpdateRunnable(final Launcher launcher, ItemInfo originalInfo,
final Handler uiHandler, final PopupContainerWithArrow container,
final List<String> shortcutIds, final List<DeepShortcutView> shortcutViews,
- final String[] notificationKeys, final NotificationItemView notificationView) {
+ final List<NotificationKeyData> notificationKeys,
+ final NotificationItemView notificationView) {
final ComponentName activity = originalInfo.getTargetComponent();
final UserHandle user = originalInfo.user;
return new Runnable() {
@@ -162,9 +180,11 @@
uiHandler.post(new UpdateNotificationChild(notificationView, infos));
}
- final List<ShortcutInfoCompat> shortcuts = PopupPopulator.sortAndFilterShortcuts(
- DeepShortcutManager.getInstance(launcher).queryForShortcutsContainer(
- activity, shortcutIds, user));
+ List<ShortcutInfoCompat> shortcuts = DeepShortcutManager.getInstance(launcher)
+ .queryForShortcutsContainer(activity, shortcutIds, user);
+ String shortcutIdToDeDupe = notificationKeys.isEmpty() ? null
+ : notificationKeys.get(0).shortcutId;
+ shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, shortcutIdToDeDupe);
for (int i = 0; i < shortcuts.size() && i < shortcutViews.size(); i++) {
final ShortcutInfoCompat shortcut = shortcuts.get(i);
ShortcutInfo si = new ShortcutInfo(shortcut, launcher);
@@ -196,7 +216,8 @@
@Override
public void run() {
- mShortcutChild.applyShortcutInfo(mShortcutChildInfo, mDetail, mContainer);
+ mShortcutChild.applyShortcutInfo(mShortcutChildInfo, mDetail,
+ mContainer.mShortcutsItemView);
}
}
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index 38a3e1f..4dc3c1c 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -40,6 +40,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
/**
* A frame layout which contains a QSB. This internally uses fragment to bind the view, which
@@ -89,7 +90,11 @@
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mWrapper = new FrameLayout(getActivity());
- mWrapper.addView(createQsb(mWrapper));
+
+ // Only add the view when enabled
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ mWrapper.addView(createQsb(mWrapper));
+ }
return mWrapper;
}
@@ -197,6 +202,11 @@
}
private void rebindFragment() {
+ // Exit if the embedded qsb is disabled
+ if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ return;
+ }
+
if (mWrapper != null && getActivity() != null) {
mWrapper.removeAllViews();
mWrapper.addView(createQsb(mWrapper));
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
index 2f07c9a..47a023e 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
@@ -17,26 +17,30 @@
package com.android.launcher3.shortcuts;
import android.content.Context;
+import android.graphics.Point;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
+import android.widget.FrameLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.popup.PopupItemView;
+import com.android.launcher3.Utilities;
/**
* A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}.
* This lets us animate the DeepShortcutView (icon and text) separately from the background.
*/
-public class DeepShortcutView extends PopupItemView {
+public class DeepShortcutView extends FrameLayout {
+
+ private static final Point sTempPoint = new Point();
private final Rect mPillRect;
private DeepShortcutTextView mBubbleText;
+ private View mIconView;
private ShortcutInfo mInfo;
private ShortcutInfoCompat mDetail;
@@ -59,6 +63,7 @@
protected void onFinishInflate() {
super.onFinishInflate();
mBubbleText = (DeepShortcutTextView) findViewById(R.id.deep_shortcut);
+ mIconView = findViewById(R.id.icon);
}
public DeepShortcutTextView getBubbleText() {
@@ -73,6 +78,17 @@
return mIconView.getVisibility() == View.VISIBLE;
}
+ /**
+ * Returns the position of the center of the icon relative to the container.
+ */
+ public Point getIconCenter() {
+ sTempPoint.y = sTempPoint.x = getMeasuredHeight() / 2;
+ if (Utilities.isRtl(getResources())) {
+ sTempPoint.x = getMeasuredWidth() - sTempPoint.x;
+ }
+ return sTempPoint;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -81,7 +97,7 @@
/** package private **/
public void applyShortcutInfo(ShortcutInfo info, ShortcutInfoCompat detail,
- PopupContainerWithArrow container) {
+ ShortcutsItemView container) {
mInfo = info;
mDetail = detail;
mBubbleText.applyFromShortcutInfo(info);
diff --git a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
index dac2160..37047bb 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
@@ -44,15 +44,12 @@
}
@TargetApi(Build.VERSION_CODES.N)
- public Intent makeIntent(Context context) {
- long serialNumber = UserManagerCompat.getInstance(context)
- .getSerialNumberForUser(getUserHandle());
+ public Intent makeIntent() {
return new Intent(Intent.ACTION_MAIN)
.addCategory(INTENT_CATEGORY)
.setComponent(getActivity())
.setPackage(getPackage())
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- .putExtra(ItemInfo.EXTRA_PROFILE, serialNumber)
.putExtra(EXTRA_SHORTCUT_ID, getId());
}
diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
new file mode 100644
index 0000000..349c4c9
--- /dev/null
+++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
@@ -0,0 +1,180 @@
+/*
+ * 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.shortcuts;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.content.Context;
+import android.graphics.Point;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.PropertyListBuilder;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
+import com.android.launcher3.popup.PopupContainerWithArrow;
+import com.android.launcher3.popup.PopupItemView;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link PopupItemView} that contains all of the {@link DeepShortcutView}s for an app.
+ */
+public class ShortcutsItemView extends PopupItemView implements View.OnLongClickListener,
+ View.OnTouchListener, LogContainerProvider {
+
+ private Launcher mLauncher;
+ private LinearLayout mDeepShortcutsLayout;
+ private final Point mIconShift = new Point();
+ private final Point mIconLastTouchPos = new Point();
+
+ public ShortcutsItemView(Context context) {
+ this(context, null, 0);
+ }
+
+ public ShortcutsItemView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ShortcutsItemView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mLauncher = Launcher.getLauncher(context);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mDeepShortcutsLayout = (LinearLayout) findViewById(R.id.deep_shortcuts);
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent ev) {
+ // Touched a shortcut, update where it was touched so we can drag from there on long click.
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
+ break;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ // Return early if this is not initiated from a touch or not the correct view
+ if (!v.isInTouchMode() || !(v.getParent() instanceof DeepShortcutView)) return false;
+ // Return early if global dragging is not enabled
+ if (!mLauncher.isDraggingEnabled()) return false;
+ // Return early if an item is already being dragged (e.g. when long-pressing two shortcuts)
+ if (mLauncher.getDragController().isDragging()) return false;
+
+ // Long clicked on a shortcut.
+ DeepShortcutView sv = (DeepShortcutView) v.getParent();
+ sv.setWillDrawIcon(false);
+
+ // Move the icon to align with the center-top of the touch point
+ mIconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
+ mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx;
+
+ DragView dv = mLauncher.getWorkspace().beginDragShared(sv.getBubbleText(),
+ (PopupContainerWithArrow) getParent(), sv.getFinalInfo(),
+ new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions());
+ dv.animateShift(-mIconShift.x, -mIconShift.y);
+
+ // TODO: support dragging from within folder without having to close it
+ AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_FOLDER);
+ return false;
+ }
+
+ public void addDeepShortcutView(DeepShortcutView deepShortcutView) {
+ if (getNumDeepShortcuts() > 0) {
+ getDeepShortcutAt(getNumDeepShortcuts() - 1).findViewById(R.id.divider)
+ .setVisibility(VISIBLE);
+ }
+ mDeepShortcutsLayout.addView(deepShortcutView);
+ }
+
+ private DeepShortcutView getDeepShortcutAt(int index) {
+ return (DeepShortcutView) mDeepShortcutsLayout.getChildAt(index);
+ }
+
+ private int getNumDeepShortcuts() {
+ return mDeepShortcutsLayout.getChildCount();
+ }
+
+ public List<DeepShortcutView> getDeepShortcutViews(boolean reverseOrder) {
+ int numDeepShortcuts = getNumDeepShortcuts();
+ List<DeepShortcutView> deepShortcutViews = new ArrayList<>(numDeepShortcuts);
+ for (int i = 0; i < numDeepShortcuts; i++) {
+ DeepShortcutView deepShortcut = getDeepShortcutAt(i);
+ if (reverseOrder) {
+ deepShortcutViews.add(0, deepShortcut);
+ } else {
+ deepShortcutViews.add(deepShortcut);
+ }
+ }
+ return deepShortcutViews;
+ }
+
+ @Override
+ public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) {
+ AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet();
+ openAnimation.play(super.createOpenAnimation(isContainerAboveIcon, pivotLeft));
+ for (int i = 0; i < getNumDeepShortcuts(); i++) {
+ View deepShortcutIcon = getDeepShortcutAt(i).getIconView();
+ deepShortcutIcon.setScaleX(0);
+ deepShortcutIcon.setScaleY(0);
+ openAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder(
+ deepShortcutIcon, new PropertyListBuilder().scale(1).build()));
+ }
+ return openAnimation;
+ }
+
+ @Override
+ public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft,
+ long duration) {
+ AnimatorSet closeAnimation = LauncherAnimUtils.createAnimatorSet();
+ closeAnimation.play(super.createCloseAnimation(isContainerAboveIcon, pivotLeft, duration));
+ for (int i = 0; i < getNumDeepShortcuts(); i++) {
+ View deepShortcutIcon = getDeepShortcutAt(i).getIconView();
+ deepShortcutIcon.setScaleX(1);
+ deepShortcutIcon.setScaleY(1);
+ closeAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder(
+ deepShortcutIcon, new PropertyListBuilder().scale(0).build()));
+ }
+ return closeAnimation;
+ }
+
+ @Override
+ public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
+ LauncherLogProto.Target targetParent) {
+ target.itemType = LauncherLogProto.ItemType.DEEPSHORTCUT;
+ target.rank = info.rank;
+ targetParent.containerType = LauncherLogProto.ContainerType.DEEPSHORTCUTS;
+ }
+}
diff --git a/src/com/android/launcher3/testing/LauncherExtension.java b/src/com/android/launcher3/testing/LauncherExtension.java
index 6797c7b..aedca8d 100644
--- a/src/com/android/launcher3/testing/LauncherExtension.java
+++ b/src/com/android/launcher3/testing/LauncherExtension.java
@@ -180,9 +180,6 @@
}
@Override
- public UserEventDispatcher getUserEventDispatcher() { return null; }
-
- @Override
public View getQsbBar() {
return null;
}
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index a1c2f0a..ce603c4 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -21,6 +21,7 @@
import android.content.pm.LauncherActivityInfo;
import android.os.Process;
import android.os.UserHandle;
+import android.support.v4.os.BuildCompat;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
@@ -31,6 +32,7 @@
import com.android.launcher3.LauncherModel;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
+import com.android.launcher3.SessionCommitReceiver;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@@ -68,12 +70,15 @@
private final LauncherModel mModel;
private final UserHandle mUser;
private final IconCache mIconCache;
+ private final boolean mAddIconsToHomescreen;
private ManagedProfileHeuristic(Context context, UserHandle user) {
mContext = context;
mUser = user;
mModel = LauncherAppState.getInstance(context).getModel();
mIconCache = LauncherAppState.getInstance(context).getIconCache();
+ mAddIconsToHomescreen =
+ !BuildCompat.isAtLeastO() || SessionCommitReceiver.isEnabled(context);
}
public void processPackageRemoved(String[] packages) {
@@ -116,7 +121,7 @@
.isQuietModeEnabled(user);
for (int i = 0; i < count; i++) {
LauncherActivityInstallInfo info = apps.get(i);
- AppInfo appInfo = new AppInfo(mContext, info.info, user, quietModeEnabled);
+ AppInfo appInfo = new AppInfo(info.info, user, quietModeEnabled);
mIconCache.getTitleAndIcon(appInfo, info.info, false /* useLowResIcon */);
ShortcutInfo si = appInfo.makeShortcut();
((info.installTime <= folderCreationTime) ? workFolderApps : homescreenApps).add(si);
@@ -127,7 +132,7 @@
// Do not add shortcuts on the homescreen for the first time. This prevents the launcher
// getting filled with the managed user apps, when it start with a fresh DB (or after
// a very long time).
- if (userAppsExisted && !homescreenApps.isEmpty()) {
+ if (userAppsExisted && !homescreenApps.isEmpty() && mAddIconsToHomescreen) {
mModel.addAndBindAddedWorkspaceItems(new ArrayList<ItemInfo>(homescreenApps));
}
}
@@ -147,6 +152,13 @@
}
// Try to get a work folder.
String folderIdKey = USER_FOLDER_ID_PREFIX + mUserManager.getSerialNumberForUser(user);
+ if (!mAddIconsToHomescreen) {
+ if (!mPrefs.contains(folderIdKey)) {
+ // Just mark the folder id preference to avoid new folder creation later.
+ mPrefs.edit().putLong(folderIdKey, -1).apply();
+ }
+ return;
+ }
if (mPrefs.contains(folderIdKey)) {
long folderId = mPrefs.getLong(folderIdKey, 0);
final FolderInfo workFolder = mModel.findFolderById(folderId);
@@ -163,7 +175,7 @@
@Override
public void run() {
- workFolder.prepareAutoAdd();
+ workFolder.prepareAutoUpdate();
for (ShortcutInfo info : workFolderApps) {
workFolder.add(info, false);
}
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index bfa932b..e12b2d4 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -40,81 +40,55 @@
*/
public class PackageManagerHelper {
- private static final int FLAG_SUSPENDED = 1<<30;
-
private final Context mContext;
private final PackageManager mPm;
+ private final LauncherAppsCompat mLauncherApps;
public PackageManagerHelper(Context context) {
mContext = context;
mPm = context.getPackageManager();
+ mLauncherApps = LauncherAppsCompat.getInstance(context);
}
/**
* Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't
* guarantee that the app is on SD card.
*/
- public boolean isAppOnSdcard(String packageName) {
- return isAppEnabled(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ public boolean isAppOnSdcard(String packageName, UserHandle user) {
+ ApplicationInfo info = mLauncherApps.getApplicationInfo(
+ packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, user);
+ return info != null && (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
- public boolean isAppEnabled(String packageName) {
- return isAppEnabled(packageName, 0);
- }
-
- public boolean isAppEnabled(String packageName, int flags) {
- try {
- ApplicationInfo info = mPm.getApplicationInfo(packageName, flags);
- return info != null && info.enabled;
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
- /**
- * Returns whether a package is suspended for the current user as per
- * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
- */
- public boolean isAppSuspended(String packageName) {
- try {
- ApplicationInfo info = mPm.getApplicationInfo(packageName, 0);
- return info != null && isAppSuspended(info);
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
- /**
- * Returns whether the target app is suspended for a given user as per
- * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
- */
+ /**
+ * Returns whether the target app is suspended for a given user as per
+ * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
+ */
public boolean isAppSuspended(String packageName, UserHandle user) {
- ApplicationInfo info =
- LauncherAppsCompat.getInstance(mContext).getApplicationInfo(packageName, user);
+ ApplicationInfo info = mLauncherApps.getApplicationInfo(packageName, 0, user);
return info != null && isAppSuspended(info);
}
public boolean isSafeMode() {
- return mPm.isSafeMode();
+ return mContext.getPackageManager().isSafeMode();
}
public Intent getAppLaunchIntent(String pkg, UserHandle user) {
- List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(mContext)
- .getActivityList(pkg, user);
+ List<LauncherActivityInfo> activities = mLauncherApps.getActivityList(pkg, user);
return activities.isEmpty() ? null :
- AppInfo.makeLaunchIntent(mContext, activities.get(0), user);
+ AppInfo.makeLaunchIntent(activities.get(0));
}
- /**
- * Returns whether an application is suspended as per
- * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
- */
+ /**
+ * Returns whether an application is suspended as per
+ * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
+ */
public static boolean isAppSuspended(ApplicationInfo info) {
// The value of FLAG_SUSPENDED was reused by a hidden constant
// ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N
// or later.
if (Utilities.ATLEAST_NOUGAT) {
- return (info.flags & FLAG_SUSPENDED) != 0;
+ return (info.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
} else {
return false;
}
diff --git a/src/com/android/launcher3/util/PendingRequestArgs.java b/src/com/android/launcher3/util/PendingRequestArgs.java
index 538e1df..dabd40d 100644
--- a/src/com/android/launcher3/util/PendingRequestArgs.java
+++ b/src/com/android/launcher3/util/PendingRequestArgs.java
@@ -53,6 +53,7 @@
public PendingRequestArgs(Parcel parcel) {
readFromValues(ContentValues.CREATOR.createFromParcel(parcel));
+ user = parcel.readParcelable(null);
mArg1 = parcel.readInt();
mObjectType = parcel.readInt();
@@ -69,6 +70,7 @@
ContentValues itemValues = new ContentValues();
writeToValues(new ContentWriter(itemValues, null));
itemValues.writeToParcel(dest, flags);
+ dest.writeParcelable(user, flags);
dest.writeInt(mArg1);
dest.writeInt(mObjectType);
diff --git a/src/com/android/launcher3/util/PillWidthRevealOutlineProvider.java b/src/com/android/launcher3/util/PillWidthRevealOutlineProvider.java
deleted file mode 100644
index 89dda3b..0000000
--- a/src/com/android/launcher3/util/PillWidthRevealOutlineProvider.java
+++ /dev/null
@@ -1,41 +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.graphics.Rect;
-
-/**
- * Extension of {@link PillRevealOutlineProvider} which only changes the width of the pill.
- */
-public class PillWidthRevealOutlineProvider extends PillRevealOutlineProvider {
-
- private final int mStartLeft;
- private final int mStartRight;
-
- public PillWidthRevealOutlineProvider(Rect pillRect, int left, int right) {
- super(0, 0, pillRect);
- mOutline.set(pillRect);
- mStartLeft = left;
- mStartRight = right;
- }
-
- @Override
- public void setProgress(float progress) {
- mOutline.left = (int) (progress * mPillRect.left + (1 - progress) * mStartLeft);
- mOutline.right = (int) (progress * mPillRect.right + (1 - progress) * mStartRight);
- }
-}
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index acd589e..d863339 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -18,6 +18,8 @@
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.ColorMatrix;
import android.view.ContextThemeWrapper;
/**
@@ -49,4 +51,21 @@
ta.recycle();
return (int) (255 * alpha + 0.5f);
}
+
+ /**
+ * Scales a color matrix such that, when applied to color R G B A, it produces R' G' B' A' where
+ * R' = r * R
+ * G' = g * G
+ * B' = b * B
+ * A' = a * A
+ *
+ * The matrix will, for instance, turn white into r g b a, and black will remain black.
+ *
+ * @param color The color r g b a
+ * @param target The ColorMatrix to scale
+ */
+ public static void setColorScaleOnMatrix(int color, ColorMatrix target) {
+ target.setScale(Color.red(color) / 255f, Color.green(color) / 255f,
+ Color.blue(color) / 255f, Color.alpha(color) / 255f);
+ }
}
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 6f4c286..b411879 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -23,6 +23,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
+import android.widget.RemoteViews;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
@@ -32,6 +33,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.LivePreviewWidgetCell;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.graphics.HolographicOutlineHelper;
import com.android.launcher3.graphics.LauncherIcons;
@@ -47,12 +49,17 @@
private final PendingAddItemInfo mAddInfo;
private Bitmap mPreviewBitmap;
+ private RemoteViews mPreview;
public PendingItemDragHelper(View view) {
super(view);
mAddInfo = (PendingAddItemInfo) view.getTag();
}
+ public void setPreview(RemoteViews preview) {
+ mPreview = preview;
+ }
+
/**
* Starts the drag for the pending item associated with the view.
*
@@ -67,7 +74,7 @@
final Launcher launcher = Launcher.getLauncher(mView.getContext());
LauncherAppState app = LauncherAppState.getInstance(launcher);
- final Bitmap preview;
+ Bitmap preview = null;
final float scale;
final Point dragOffset;
final Rect dragRegion;
@@ -80,8 +87,15 @@
int maxWidth = Math.min((int) (previewBitmapWidth * MAX_WIDGET_SCALE), size[0]);
int[] previewSizeBeforeScale = new int[1];
- preview = app.getWidgetCache() .generateWidgetPreview(
- launcher, createWidgetInfo.info, maxWidth, null, previewSizeBeforeScale);
+
+ if (mPreview != null) {
+ preview = LivePreviewWidgetCell.generateFromRemoteViews(launcher, mPreview,
+ createWidgetInfo.info, maxWidth, previewSizeBeforeScale);
+ }
+ if (preview == null) {
+ preview = app.getWidgetCache().generateWidgetPreview(
+ launcher, createWidgetInfo.info, maxWidth, null, previewSizeBeforeScale);
+ }
if (previewSizeBeforeScale[0] < previewBitmapWidth) {
// The icon has extra padding around it.
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 455ec4e..3bf622e 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.graphics.Bitmap;
+import android.os.CancellationSignal;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -34,7 +35,6 @@
import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.WidgetPreviewLoader;
-import com.android.launcher3.WidgetPreviewLoader.PreviewLoadRequest;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.model.WidgetItem;
@@ -60,20 +60,21 @@
/** Widget preview width is calculated by multiplying this factor to the widget cell width. */
private static final float PREVIEW_SCALE = 0.8f;
- private int mPresetPreviewSize;
+ protected int mPresetPreviewSize;
private int mCellSize;
private WidgetImageView mWidgetImage;
private TextView mWidgetName;
private TextView mWidgetDims;
- private WidgetItem mItem;
+ protected WidgetItem mItem;
private WidgetPreviewLoader mWidgetPreviewLoader;
- private PreviewLoadRequest mActiveRequest;
private StylusEventHelper mStylusEventHelper;
- private final BaseActivity mActivity;
+ protected CancellationSignal mActiveRequest;
+
+ protected final BaseActivity mActivity;
public WidgetCell(Context context) {
this(context, null);
@@ -123,7 +124,7 @@
mWidgetDims.setText(null);
if (mActiveRequest != null) {
- mActiveRequest.cleanup();
+ mActiveRequest.cancel();
mActiveRequest = null;
}
}
diff --git a/src_config/com/android/launcher3/config/FeatureFlags.java b/src_config/com/android/launcher3/config/FeatureFlags.java
index 7459c0c..80eebec 100644
--- a/src_config/com/android/launcher3/config/FeatureFlags.java
+++ b/src_config/com/android/launcher3/config/FeatureFlags.java
@@ -29,6 +29,11 @@
public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
public static boolean LAUNCHER3_ALL_APPS_PULL_UP = true;
public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = false;
+ // When enabled allows to use any point on the fast scrollbar to start dragging.
+ public static boolean LAUNCHER3_DIRECT_SCROLL = true;
+ // When enabled while all-apps open, the soft input will be set to adjust resize .
+ public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = false;
+
// Feature flag to enable moving the QSB on the 0th screen of the workspace.
public static final boolean QSB_ON_FIRST_SCREEN = true;
@@ -38,10 +43,12 @@
public static final boolean PULLDOWN_SEARCH = false;
// When enabled the status bar may show dark icons based on the top of the wallpaper.
public static final boolean LIGHT_STATUS_BAR = false;
- // When enabled allows to use any point on the fast scrollbar to start dragging.
- public static final boolean LAUNCHER3_DIRECT_SCROLL = true;
// When enabled icons are badged with the number of notifications associated with that app.
public static final boolean BADGE_ICONS = true;
// When enabled, icons not supporting {@link MaskableIconDrawable} will be wrapped in this class.
public static final boolean LEGACY_ICON_TREATMENT = false;
+ // When enabled, adaptive icons would have shadows baked when being stored to icon cache.
+ public static final boolean ADAPTIVE_ICON_SHADOW = true;
+ // When enabled, app discovery will be enabled if service is implemented
+ public static final boolean DISCOVERY_ENABLED = false;
}
diff --git a/tests/res/layout/test_layout_appwidget_view.xml b/tests/res/layout/test_layout_appwidget_view.xml
new file mode 100644
index 0000000..7c87e60
--- /dev/null
+++ b/tests/res/layout/test_layout_appwidget_view.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#FFFF00">
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="20dp"
+ android:background="#FF0000"
+ android:id="@android:id/icon" />
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 0843d9b..2ad9b35 100644
--- a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -58,11 +58,34 @@
MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
}
+ @Test
+ public void testDeDupeShortcutId() {
+ // Successfully remove one of the shortcuts
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 2, 0, generateId(true, 1));
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 3), 0, 2, generateId(false, 1));
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 1, generateId(false, 1));
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 1, 2, generateId(true, 1));
+ // Successfully keep all shortcuts when id doesn't exist
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0, generateId(false, 1));
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0, generateId(true, 4));
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 2, generateId(false, 4));
+ filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 2, generateId(true, 4));
+ }
+
+ private String generateId(boolean isStatic, int rank) {
+ return (isStatic ? "static" : "dynamic") + rank;
+ }
+
private void filterShortcutsAndAssertNumStaticAndDynamic(
List<ShortcutInfoCompat> shortcuts, int expectedStatic, int expectedDynamic) {
+ filterShortcutsAndAssertNumStaticAndDynamic(shortcuts, expectedStatic, expectedDynamic, null);
+ }
+
+ private void filterShortcutsAndAssertNumStaticAndDynamic(List<ShortcutInfoCompat> shortcuts,
+ int expectedStatic, int expectedDynamic, String shortcutIdToRemove) {
Collections.shuffle(shortcuts);
List<ShortcutInfoCompat> filteredShortcuts = PopupPopulator.sortAndFilterShortcuts(
- shortcuts);
+ shortcuts, shortcutIdToRemove);
assertIsSorted(filteredShortcuts);
int numStatic = 0;
@@ -113,6 +136,7 @@
private class Shortcut extends ShortcutInfoCompat {
private boolean mIsStatic;
private int mRank;
+ private String mId;
public Shortcut(ShortcutInfo shortcutInfo) {
super(shortcutInfo);
@@ -122,6 +146,7 @@
this(null);
mIsStatic = isStatic;
mRank = rank;
+ mId = generateId(isStatic, rank);
}
@Override
@@ -138,5 +163,10 @@
public int getRank() {
return mRank;
}
+
+ @Override
+ public String getId() {
+ return mId;
+ }
}
}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/testcomponent/RequestPinItemActivity.java b/tests/src/com/android/launcher3/testcomponent/RequestPinItemActivity.java
index c2dd225..8580992 100644
--- a/tests/src/com/android/launcher3/testcomponent/RequestPinItemActivity.java
+++ b/tests/src/com/android/launcher3/testcomponent/RequestPinItemActivity.java
@@ -28,6 +28,7 @@
import android.graphics.Paint;
import android.graphics.drawable.Icon;
import android.os.Bundle;
+import android.widget.RemoteViews;
/**
* Sample activity to request pinning an item.
@@ -36,7 +37,8 @@
public class RequestPinItemActivity extends BaseTestingActivity {
private PendingIntent mCallback = null;
- private String mShortcutId;
+ private String mShortcutId = "test-id";
+ private int mRemoteViewColor = Color.TRANSPARENT;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -51,6 +53,10 @@
mCallback = callback;
}
+ public void setRemoteViewColor(int color) {
+ mRemoteViewColor = color;
+ }
+
public void setShortcutId(String id) {
mShortcutId = id;
}
@@ -84,6 +90,16 @@
}
private void requestWidget(ComponentName cn) {
- AppWidgetManager.getInstance(this).requestPinAppWidget(cn, mCallback);
+ Bundle extras = null;
+ if (mRemoteViewColor != Color.TRANSPARENT) {
+ int layoutId = getResources().getIdentifier(
+ "test_layout_appwidget_view", "layout", getPackageName());
+ RemoteViews views = new RemoteViews(getPackageName(), layoutId);
+ views.setInt(android.R.id.icon, "setBackgroundColor", mRemoteViewColor);
+ extras = new Bundle();
+ extras.putParcelable(AppWidgetManager.EXTRA_APPWIDGET_PREVIEW, views);
+ }
+
+ AppWidgetManager.getInstance(this).requestPinAppWidget(cn, extras, mCallback);
}
}
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index 5ef5ec1..b798dfa 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -20,6 +20,7 @@
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
+import android.graphics.Color;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
@@ -95,6 +96,23 @@
});
}
+ public void testPinWidgetNoConfig_customPreview() throws Throwable {
+ // Command to set custom preview
+ Intent command = RequestPinItemActivity.getCommandIntent(
+ RequestPinItemActivity.class, "setRemoteViewColor").putExtra(
+ RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED);
+
+ runTest("pinWidgetNoConfig", true, new ItemOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View view) {
+ return info instanceof LauncherAppWidgetInfo &&
+ ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
+ ((LauncherAppWidgetInfo) info).providerName.getClassName()
+ .equals(AppWidgetNoConfig.class.getName());
+ }
+ }, command);
+ }
+
public void testPinWidgetWithConfig() throws Throwable {
runTest("pinWidgetWithConfig", true, new ItemOperator() {
@Override
@@ -107,8 +125,12 @@
});
}
+ public void testPinShortcut() throws Throwable {
+ // Command to set the shortcut id
+ Intent command = RequestPinItemActivity.getCommandIntent(
+ RequestPinItemActivity.class, "setShortcutId").putExtra(
+ RequestPinItemActivity.EXTRA_PARAM + "0", mShortcutId);
- public void testPinWidgetShortcut() throws Throwable {
runTest("pinShortcut", false, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View view) {
@@ -116,11 +138,11 @@
info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
ShortcutKey.fromItemInfo(info).getId().equals(mShortcutId);
}
- });
+ }, command);
}
- private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher)
- throws Throwable {
+ private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher,
+ Intent... commandIntents) throws Throwable {
if (!Utilities.isAtLeastO()) {
return;
}
@@ -146,11 +168,8 @@
RequestPinItemActivity.class, "setCallback").putExtra(
RequestPinItemActivity.EXTRA_PARAM + "0", callback));
- if (!isWidget) {
- // Set shortcut id
- mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
- RequestPinItemActivity.class, "setShortcutId").putExtra(
- RequestPinItemActivity.EXTRA_PARAM + "0", mShortcutId));
+ for (Intent command : commandIntents) {
+ mTargetContext.sendBroadcast(command);
}
// call the requested method to start the flow