summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--build.gradle3
-rw-r--r--proguard.flags4
-rw-r--r--res/drawable-hdpi/ic_info_launcher.pngbin1372 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_remove_launcher.pngbin832 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_uninstall_launcher.pngbin552 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_info_launcher.pngbin689 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_remove_launcher.pngbin473 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_uninstall_launcher.pngbin378 -> 0 bytes
-rw-r--r--res/drawable-v24/ic_info_shadow.xml18
-rw-r--r--res/drawable-v24/ic_remove_shadow.xml18
-rw-r--r--res/drawable-v24/ic_uninstall_shadow.xml18
-rw-r--r--res/drawable-xhdpi/ic_info_launcher.pngbin2056 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_remove_launcher.pngbin965 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_uninstall_launcher.pngbin730 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/all_apps_alpha_mask.pngbin0 -> 16512 bytes
-rw-r--r--res/drawable-xxhdpi/ic_info_launcher.pngbin3596 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_remove_launcher.pngbin1694 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_uninstall_launcher.pngbin1058 -> 0 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_info_launcher.pngbin3276 -> 0 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_remove_launcher.pngbin1726 -> 0 bytes
-rw-r--r--res/drawable-xxxhdpi/ic_uninstall_launcher.pngbin1042 -> 0 bytes
-rw-r--r--res/drawable/ic_info_no_shadow.xml5
-rw-r--r--res/drawable/ic_remove_no_shadow.xml25
-rw-r--r--res/drawable/ic_setting.xml2
-rw-r--r--res/drawable/ic_uninstall_no_shadow.xml25
-rw-r--r--res/drawable/ic_wallpaper.xml2
-rw-r--r--res/drawable/ic_widget.xml2
-rw-r--r--res/interpolator/folder_interpolator.xml24
-rw-r--r--res/interpolator/large_folder_preview_item_interpolator.xml24
-rw-r--r--res/layout-land/launcher.xml4
-rw-r--r--res/layout-port/launcher.xml3
-rw-r--r--res/layout-sw720dp/launcher.xml3
-rw-r--r--res/layout/all_apps.xml34
-rw-r--r--res/layout/all_apps_search_container.xml42
-rw-r--r--res/layout/drop_target_bar_horz.xml2
-rw-r--r--res/layout/drop_target_bar_vert.xml2
-rw-r--r--res/layout/gradient_scrim.xml31
-rw-r--r--res/layout/hotseat.xml1
-rw-r--r--res/layout/overview_panel.xml4
-rw-r--r--res/layout/page_indicator.xml1
-rw-r--r--res/layout/system_shortcut.xml1
-rw-r--r--res/layout/system_shortcut_icon_only.xml1
-rw-r--r--res/layout/widgets_view.xml1
-rw-r--r--res/raw/downgrade_schema.json20
-rw-r--r--res/values-az/strings.xml121
-rw-r--r--res/values-be/strings.xml281
-rw-r--r--res/values-bn/config.xml13
-rw-r--r--res/values-bn/strings.xml118
-rw-r--r--res/values-bs/strings.xml121
-rw-r--r--res/values-et/strings.xml130
-rw-r--r--res/values-eu/strings.xml121
-rw-r--r--res/values-gl/strings.xml121
-rw-r--r--res/values-gu/config.xml13
-rw-r--r--res/values-gu/strings.xml118
-rw-r--r--res/values-hy/strings.xml121
-rw-r--r--res/values-is/strings.xml121
-rw-r--r--res/values-ka/strings.xml121
-rw-r--r--res/values-kk/strings.xml121
-rw-r--r--res/values-km/strings.xml121
-rw-r--r--res/values-kn/config.xml13
-rw-r--r--res/values-kn/strings.xml118
-rw-r--r--res/values-ky/strings.xml121
-rw-r--r--res/values-lo/strings.xml121
-rw-r--r--res/values-mk/strings.xml121
-rw-r--r--res/values-ml/config.xml13
-rw-r--r--res/values-ml/strings.xml118
-rw-r--r--res/values-mn/strings.xml121
-rw-r--r--res/values-mr/config.xml13
-rw-r--r--res/values-mr/strings.xml118
-rw-r--r--res/values-ms/strings.xml130
-rw-r--r--res/values-my/strings.xml121
-rw-r--r--res/values-ne/config.xml13
-rw-r--r--res/values-ne/strings.xml118
-rw-r--r--res/values-pa/config.xml13
-rw-r--r--res/values-pa/strings.xml118
-rw-r--r--res/values-si/strings.xml121
-rw-r--r--res/values-sq/strings.xml121
-rw-r--r--res/values-sw720dp/styles.xml1
-rw-r--r--res/values-ta/strings.xml121
-rw-r--r--res/values-te/config.xml13
-rw-r--r--res/values-te/strings.xml118
-rw-r--r--res/values-ur/config.xml13
-rw-r--r--res/values-ur/strings.xml118
-rw-r--r--res/values-uz/strings.xml121
-rw-r--r--res/values/attrs.xml6
-rw-r--r--res/values/colors.xml10
-rw-r--r--res/values/config.xml5
-rw-r--r--res/values/dimens.xml18
-rw-r--r--res/values/drawables.xml20
-rw-r--r--res/values/styles.xml30
-rw-r--r--res/xml/backupscheme.xml1
-rw-r--r--src/com/android/launcher3/AllAppsList.java56
-rw-r--r--src/com/android/launcher3/AutoInstallsLayout.java2
-rw-r--r--src/com/android/launcher3/BaseRecyclerView.java8
-rw-r--r--src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java5
-rw-r--r--src/com/android/launcher3/BubbleTextView.java41
-rw-r--r--src/com/android/launcher3/CellLayout.java7
-rw-r--r--src/com/android/launcher3/DeferredHandler.java120
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java2
-rw-r--r--src/com/android/launcher3/DeviceProfile.java12
-rw-r--r--src/com/android/launcher3/FocusHelper.java4
-rw-r--r--src/com/android/launcher3/Hotseat.java10
-rw-r--r--src/com/android/launcher3/InfoDropTarget.java11
-rw-r--r--src/com/android/launcher3/InsettableFrameLayout.java3
-rw-r--r--src/com/android/launcher3/InvariantDeviceProfile.java3
-rw-r--r--src/com/android/launcher3/ItemInfo.java23
-rw-r--r--src/com/android/launcher3/Launcher.java135
-rw-r--r--src/com/android/launcher3/LauncherAnimUtils.java15
-rw-r--r--src/com/android/launcher3/LauncherAppState.java4
-rw-r--r--src/com/android/launcher3/LauncherAppWidgetInfo.java6
-rw-r--r--src/com/android/launcher3/LauncherCallbacks.java88
-rw-r--r--src/com/android/launcher3/LauncherModel.java212
-rw-r--r--src/com/android/launcher3/LauncherProvider.java258
-rw-r--r--src/com/android/launcher3/LauncherSettings.java22
-rw-r--r--src/com/android/launcher3/LauncherStateTransitionAnimation.java2
-rw-r--r--src/com/android/launcher3/MainThreadExecutor.java4
-rw-r--r--src/com/android/launcher3/PagedView.java14
-rw-r--r--src/com/android/launcher3/PendingAppWidgetHostView.java11
-rw-r--r--src/com/android/launcher3/PromiseAppInfo.java52
-rw-r--r--src/com/android/launcher3/ShortcutInfo.java6
-rw-r--r--src/com/android/launcher3/UninstallDropTarget.java7
-rw-r--r--src/com/android/launcher3/Utilities.java30
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java27
-rw-r--r--src/com/android/launcher3/Workspace.java25
-rw-r--r--src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java2
-rw-r--r--src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java3
-rw-r--r--src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java1
-rw-r--r--src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java2
-rw-r--r--src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java4
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java172
-rw-r--r--src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java8
-rw-r--r--src/com/android/launcher3/allapps/AllAppsGridAdapter.java15
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java24
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java1
-rw-r--r--src/com/android/launcher3/allapps/AllAppsTransitionController.java75
-rw-r--r--src/com/android/launcher3/allapps/AlphabeticalAppsList.java16
-rw-r--r--src/com/android/launcher3/allapps/DefaultAppSearchController.java26
-rw-r--r--src/com/android/launcher3/allapps/SearchUiManager.java68
-rw-r--r--src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java (renamed from src/com/android/launcher3/allapps/AllAppsSearchBarController.java)39
-rw-r--r--src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java211
-rw-r--r--src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java (renamed from src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java)2
-rw-r--r--src/com/android/launcher3/allapps/search/HeaderElevationController.java (renamed from src/com/android/launcher3/allapps/HeaderElevationController.java)2
-rw-r--r--src/com/android/launcher3/anim/CircleRevealOutlineProvider.java (renamed from src/com/android/launcher3/util/CircleRevealOutlineProvider.java)2
-rw-r--r--src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java2
-rw-r--r--src/com/android/launcher3/anim/PillRevealOutlineProvider.java (renamed from src/com/android/launcher3/util/PillRevealOutlineProvider.java)2
-rw-r--r--src/com/android/launcher3/anim/RevealOutlineAnimation.java (renamed from src/com/android/launcher3/util/RevealOutlineAnimation.java)6
-rw-r--r--src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java57
-rw-r--r--src/com/android/launcher3/compat/LauncherAppsCompat.java4
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompat.java31
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompatVL.java72
-rw-r--r--src/com/android/launcher3/discovery/AppDiscoveryItem.java1
-rw-r--r--src/com/android/launcher3/dragndrop/DragOptions.java2
-rw-r--r--src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java1
-rw-r--r--src/com/android/launcher3/dynamicui/ColorExtractionService.java34
-rw-r--r--src/com/android/launcher3/dynamicui/ExtractedColors.java128
-rw-r--r--src/com/android/launcher3/dynamicui/colorextraction/ColorExtractor.java136
-rw-r--r--src/com/android/launcher3/dynamicui/colorextraction/WallpaperColorsCompat.java69
-rw-r--r--src/com/android/launcher3/dynamicui/colorextraction/types/ExtractionType.java23
-rw-r--r--src/com/android/launcher3/dynamicui/colorextraction/types/Tonal.java299
-rw-r--r--src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java32
-rw-r--r--src/com/android/launcher3/folder/Folder.java190
-rw-r--r--src/com/android/launcher3/folder/FolderAnimationManager.java362
-rw-r--r--src/com/android/launcher3/folder/FolderIcon.java104
-rw-r--r--src/com/android/launcher3/folder/FolderIconPreviewVerifier.java64
-rw-r--r--src/com/android/launcher3/folder/FolderPagedView.java72
-rw-r--r--src/com/android/launcher3/folder/PreviewImageView.java1
-rw-r--r--src/com/android/launcher3/folder/StackFolderIconLayoutRule.java15
-rw-r--r--src/com/android/launcher3/graphics/DragPreviewProvider.java4
-rw-r--r--src/com/android/launcher3/graphics/GradientView.java140
-rw-r--r--src/com/android/launcher3/graphics/HolographicOutlineHelper.java4
-rw-r--r--src/com/android/launcher3/graphics/IconShapeOverride.java4
-rw-r--r--src/com/android/launcher3/graphics/ScrimView.java114
-rw-r--r--src/com/android/launcher3/graphics/ShadowDrawable.java191
-rw-r--r--src/com/android/launcher3/graphics/ShadowGenerator.java50
-rw-r--r--src/com/android/launcher3/keyboard/CustomActionsPopup.java2
-rw-r--r--src/com/android/launcher3/logging/FileLog.java11
-rw-r--r--src/com/android/launcher3/logging/LoggerUtils.java1
-rw-r--r--src/com/android/launcher3/logging/UserEventDispatcher.java4
-rw-r--r--src/com/android/launcher3/model/AddWorkspaceItemsTask.java19
-rw-r--r--src/com/android/launcher3/model/BgDataModel.java12
-rw-r--r--src/com/android/launcher3/model/CacheDataUpdatedTask.java1
-rw-r--r--src/com/android/launcher3/model/DbDowngradeHelper.java108
-rw-r--r--src/com/android/launcher3/model/LoaderCursor.java2
-rw-r--r--src/com/android/launcher3/model/ModelWriter.java4
-rw-r--r--src/com/android/launcher3/model/PackageInstallStateChangedTask.java42
-rw-r--r--src/com/android/launcher3/model/PackageUpdatedTask.java27
-rw-r--r--src/com/android/launcher3/model/SdCardAvailableReceiver.java1
-rw-r--r--src/com/android/launcher3/model/ShortcutsChangedTask.java1
-rw-r--r--src/com/android/launcher3/model/UserLockStateChangedTask.java1
-rw-r--r--src/com/android/launcher3/model/WidgetsModel.java4
-rw-r--r--src/com/android/launcher3/pageindicators/CaretDrawable.java5
-rw-r--r--src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java2
-rw-r--r--src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java2
-rw-r--r--src/com/android/launcher3/popup/PopupItemView.java2
-rw-r--r--src/com/android/launcher3/popup/PopupPopulator.java6
-rw-r--r--src/com/android/launcher3/popup/SystemShortcut.java6
-rw-r--r--src/com/android/launcher3/provider/ImportDataTask.java10
-rw-r--r--src/com/android/launcher3/provider/LauncherDbUtils.java63
-rw-r--r--src/com/android/launcher3/provider/LossyScreenMigrationTask.java2
-rw-r--r--src/com/android/launcher3/provider/RestoreDbTask.java8
-rw-r--r--src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java2
-rw-r--r--src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java4
-rw-r--r--src/com/android/launcher3/testing/LauncherExtension.java13
-rw-r--r--src/com/android/launcher3/util/FocusLogic.java1
-rw-r--r--src/com/android/launcher3/util/IOUtils.java55
-rw-r--r--src/com/android/launcher3/util/LooperExecutor.java (renamed from src/com/android/launcher3/util/LooperExecuter.java)4
-rw-r--r--src/com/android/launcher3/util/LooperIdleLock.java71
-rw-r--r--src/com/android/launcher3/util/PackageManagerHelper.java18
-rw-r--r--src/com/android/launcher3/util/Preconditions.java10
-rw-r--r--src/com/android/launcher3/util/SQLiteCacheHelper.java4
-rw-r--r--src/com/android/launcher3/util/TestingUtils.java2
-rw-r--r--src/com/android/launcher3/util/ViewOnDrawExecutor.java10
-rw-r--r--src/com/android/launcher3/widget/WidgetsRecyclerView.java3
-rw-r--r--src_config/com/android/launcher3/BuildConfig.java (renamed from src_config/com/android/launcher3/config/ProviderConfig.java)14
-rw-r--r--src_flags/com/android/launcher3/config/FeatureFlags.java (renamed from src_config/com/android/launcher3/config/FeatureFlags.java)16
-rw-r--r--tests/res/raw/db_schema_v10.json4
-rw-r--r--tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java (renamed from tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java)2
-rw-r--r--tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java4
-rw-r--r--tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java14
-rw-r--r--tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java194
-rw-r--r--tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java5
-rw-r--r--tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java5
-rw-r--r--tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java5
224 files changed, 7630 insertions, 1598 deletions
diff --git a/Android.mk b/Android.mk
index 713d0828a..6cb40c51a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -31,6 +31,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
$(call all-java-files-under, src_config) \
+ $(call all-java-files-under, src_flags) \
$(call all-proto-files-under, protos)
LOCAL_RESOURCE_DIR := \
diff --git a/build.gradle b/build.gradle
index 9c71693f7..ef782d90d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -39,7 +39,7 @@ android {
sourceSets {
main {
res.srcDirs = ['res']
- java.srcDirs = ['src', 'src_config']
+ java.srcDirs = ['src', 'src_flags']
manifest.srcFile 'AndroidManifest-common.xml'
proto.srcDirs 'protos/'
}
@@ -92,6 +92,7 @@ protobuf {
remove java
javanano {
option "java_package=launcher_log.proto|com.android.launcher3.userevent.nano"
+ option "java_package=launcher_dump.proto|com.android.launcher3.model.nano"
option "enum_style=java"
}
}
diff --git a/proguard.flags b/proguard.flags
index 6cbab08e2..2ad9cacf2 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -82,6 +82,10 @@
*;
}
+-keep class com.android.launcher3.graphics.ShadowDrawable {
+ public <init>(...);
+}
+
# Proguard will strip methods required for talkback to properly scroll to
# next row when focus is on the last item of last row when using a RecyclerView
# Keep optimized and shrunk proguard to prevent issues like this when using
diff --git a/res/drawable-hdpi/ic_info_launcher.png b/res/drawable-hdpi/ic_info_launcher.png
deleted file mode 100644
index 11162e1e7..000000000
--- a/res/drawable-hdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_remove_launcher.png b/res/drawable-hdpi/ic_remove_launcher.png
deleted file mode 100644
index ad2b9af24..000000000
--- a/res/drawable-hdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_uninstall_launcher.png b/res/drawable-hdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 426683c6d..000000000
--- a/res/drawable-hdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_info_launcher.png b/res/drawable-mdpi/ic_info_launcher.png
deleted file mode 100644
index 6fbe5e395..000000000
--- a/res/drawable-mdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_remove_launcher.png b/res/drawable-mdpi/ic_remove_launcher.png
deleted file mode 100644
index 2bb281d59..000000000
--- a/res/drawable-mdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_uninstall_launcher.png b/res/drawable-mdpi/ic_uninstall_launcher.png
deleted file mode 100644
index bfcbc6dfa..000000000
--- a/res/drawable-mdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-v24/ic_info_shadow.xml b/res/drawable-v24/ic_info_shadow.xml
new file mode 100644
index 000000000..9bd7e16d0
--- /dev/null
+++ b/res/drawable-v24/ic_info_shadow.xml
@@ -0,0 +1,18 @@
+<?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.graphics.ShadowDrawable
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_info_no_shadow" />
diff --git a/res/drawable-v24/ic_remove_shadow.xml b/res/drawable-v24/ic_remove_shadow.xml
new file mode 100644
index 000000000..16a630e5f
--- /dev/null
+++ b/res/drawable-v24/ic_remove_shadow.xml
@@ -0,0 +1,18 @@
+<?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.graphics.ShadowDrawable
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_remove_no_shadow" />
diff --git a/res/drawable-v24/ic_uninstall_shadow.xml b/res/drawable-v24/ic_uninstall_shadow.xml
new file mode 100644
index 000000000..2532157ab
--- /dev/null
+++ b/res/drawable-v24/ic_uninstall_shadow.xml
@@ -0,0 +1,18 @@
+<?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.graphics.ShadowDrawable
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_uninstall_no_shadow" />
diff --git a/res/drawable-xhdpi/ic_info_launcher.png b/res/drawable-xhdpi/ic_info_launcher.png
deleted file mode 100644
index 041f2b3c0..000000000
--- a/res/drawable-xhdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_remove_launcher.png b/res/drawable-xhdpi/ic_remove_launcher.png
deleted file mode 100644
index ff94eb8e9..000000000
--- a/res/drawable-xhdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_uninstall_launcher.png b/res/drawable-xhdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 2c7ab56e9..000000000
--- a/res/drawable-xhdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/all_apps_alpha_mask.png b/res/drawable-xxhdpi/all_apps_alpha_mask.png
new file mode 100644
index 000000000..ed53ff924
--- /dev/null
+++ b/res/drawable-xxhdpi/all_apps_alpha_mask.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_info_launcher.png b/res/drawable-xxhdpi/ic_info_launcher.png
deleted file mode 100644
index 8e602da02..000000000
--- a/res/drawable-xxhdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_remove_launcher.png b/res/drawable-xxhdpi/ic_remove_launcher.png
deleted file mode 100644
index 78ca0804c..000000000
--- a/res/drawable-xxhdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_uninstall_launcher.png b/res/drawable-xxhdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 43aba6ec0..000000000
--- a/res/drawable-xxhdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_info_launcher.png b/res/drawable-xxxhdpi/ic_info_launcher.png
deleted file mode 100644
index 3540de1a1..000000000
--- a/res/drawable-xxxhdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_remove_launcher.png b/res/drawable-xxxhdpi/ic_remove_launcher.png
deleted file mode 100644
index 418d81ad6..000000000
--- a/res/drawable-xxxhdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_uninstall_launcher.png b/res/drawable-xxxhdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 724437a2a..000000000
--- a/res/drawable-xxxhdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_info_no_shadow.xml b/res/drawable/ic_info_no_shadow.xml
index 3d0c6d6e4..91a3a565a 100644
--- a/res/drawable/ic_info_no_shadow.xml
+++ b/res/drawable/ic_info_no_shadow.xml
@@ -17,8 +17,9 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/textColorPrimary" >
<path
- android:fillColor="@color/workspace_icon_text_color"
+ android:fillColor="#FFFFFFFF"
android:pathData="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/>
</vector>
diff --git a/res/drawable/ic_remove_no_shadow.xml b/res/drawable/ic_remove_no_shadow.xml
new file mode 100644
index 000000000..ef538a611
--- /dev/null
+++ b/res/drawable/ic_remove_no_shadow.xml
@@ -0,0 +1,25 @@
+<?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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/textColorPrimary" >
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
+</vector>
diff --git a/res/drawable/ic_setting.xml b/res/drawable/ic_setting.xml
index e89c158c8..b0009c59e 100644
--- a/res/drawable/ic_setting.xml
+++ b/res/drawable/ic_setting.xml
@@ -19,6 +19,6 @@ Copyright (C) 2016 The Android Open Source Project
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
- android:fillColor="@color/workspace_icon_text_color"
+ android:fillColor="?android:attr/textColorPrimary"
android:pathData="M38.86 25.95c.08-.64 .14-1.29 .14-1.95s-.06-1.31-.14-1.95l4.23-3.31c.38-.3 .49-.84 .24-1.28l-4-6.93c-.25-.43-.77-.61-1.22-.43l-4.98 2.01c-1.03-.79-2.16-1.46-3.38-1.97L29 4.84c-.09-.47-.5-.84-1-.84h-8c-.5 0-.91 .37-.99 .84l-.75 5.3c-1.22 .51-2.35 1.17-3.38 1.97L9.9 10.1c-.45-.17-.97 0-1.22 .43l-4 6.93c-.25 .43-.14 .97 .24 1.28l4.22 3.31C9.06 22.69 9 23.34 9 24s.06 1.31 .14 1.95l-4.22 3.31c-.38 .3-.49 .84-.24 1.28l4 6.93c.25 .43 .77 .61 1.22 .43l4.98-2.01c1.03 .79 2.16 1.46 3.38 1.97l.75 5.3c.08 .47 .49 .84 .99 .84h8c.5 0 .91-.37 .99-.84l.75-5.3c1.22-.51 2.35-1.17 3.38-1.97l4.98 2.01c.45 .17 .97 0 1.22-.43l4-6.93c.25-.43 .14-.97-.24-1.28l-4.22-3.31zM24 31c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/>
</vector>
diff --git a/res/drawable/ic_uninstall_no_shadow.xml b/res/drawable/ic_uninstall_no_shadow.xml
new file mode 100644
index 000000000..5bab4222e
--- /dev/null
+++ b/res/drawable/ic_uninstall_no_shadow.xml
@@ -0,0 +1,25 @@
+<?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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/textColorPrimary" >
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
+</vector>
diff --git a/res/drawable/ic_wallpaper.xml b/res/drawable/ic_wallpaper.xml
index b7fcfbf55..30f6d1ae4 100644
--- a/res/drawable/ic_wallpaper.xml
+++ b/res/drawable/ic_wallpaper.xml
@@ -19,6 +19,6 @@ Copyright (C) 2016 The Android Open Source Project
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
- android:fillColor="@color/workspace_icon_text_color"
+ android:fillColor="?android:attr/textColorPrimary"
android:pathData="M8 8h14V4H8C5.79 4 4 5.79 4 8v14h4V8zm12 18l-8 10h24l-6-8-4.06 5.42L20 26zm14-9c0-1.66-1.34-3-3-3s-3 1.34-3 3 1.34 3 3 3 3-1.34 3-3zm6-13H26v4h14v14h4V8c0-2.21-1.79-4-4-4zm0 36H26v4h14c2.21 0 4-1.79 4-4V26h-4v14zM8 26H4v14c0 2.21 1.79 4 4 4h14v-4H8V26z"/>
</vector>
diff --git a/res/drawable/ic_widget.xml b/res/drawable/ic_widget.xml
index 97706e36d..6c1469daa 100644
--- a/res/drawable/ic_widget.xml
+++ b/res/drawable/ic_widget.xml
@@ -19,6 +19,6 @@ Copyright (C) 2016 The Android Open Source Project
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
- android:fillColor="@color/workspace_icon_text_color"
+ android:fillColor="?android:attr/textColorPrimary"
android:pathData="M26 26v16h16V26H26zM6 42h16V26H6v16zM6 6v16h16V6H6zm27.31-2.63L22 14.69 33.31 26l11.31-11.31L33.31 3.37z"/>
</vector>
diff --git a/res/interpolator/folder_interpolator.xml b/res/interpolator/folder_interpolator.xml
new file mode 100644
index 000000000..b95d4548f
--- /dev/null
+++ b/res/interpolator/folder_interpolator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0.2"
+ android:controlY1="0"
+ android:controlX2="0"
+ android:controlY2="1"/>
diff --git a/res/interpolator/large_folder_preview_item_interpolator.xml b/res/interpolator/large_folder_preview_item_interpolator.xml
new file mode 100644
index 000000000..dcf01579b
--- /dev/null
+++ b/res/interpolator/large_folder_preview_item_interpolator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0"
+ android:controlY1="1"
+ android:controlX2="0"
+ android:controlY2="1"/>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index ef0dfdcc6..1e82f2276 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -35,12 +35,15 @@
<!-- The workspace contains 5 screens of cells -->
<!-- DO NOT CHANGE THE ID -->
<com.android.launcher3.Workspace
+ android:theme="@style/HomeScreenElementTheme"
android:id="@+id/workspace"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
launcher:pageIndicator="@id/page_indicator" />
+ <include layout="@layout/gradient_scrim" />
+
<!-- DO NOT CHANGE THE ID -->
<include layout="@layout/hotseat"
android:id="@+id/hotseat"
@@ -59,6 +62,7 @@
<com.android.launcher3.pageindicators.PageIndicatorCaretLandscape
android:id="@+id/page_indicator"
+ android:theme="@style/HomeScreenElementTheme"
android:layout_width="@dimen/dynamic_grid_page_indicator_height"
android:layout_height="@dimen/dynamic_grid_page_indicator_height"
android:layout_gravity="bottom|left"/>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index dd981dd20..c15e53d8d 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -36,6 +36,7 @@
<!-- The workspace contains 5 screens of cells -->
<!-- DO NOT CHANGE THE ID -->
<com.android.launcher3.Workspace
+ android:theme="@style/HomeScreenElementTheme"
android:id="@+id/workspace"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -43,6 +44,8 @@
launcher:pageIndicator="@+id/page_indicator">
</com.android.launcher3.Workspace>
+ <include layout="@layout/gradient_scrim" />
+
<!-- DO NOT CHANGE THE ID -->
<include layout="@layout/hotseat"
android:id="@+id/hotseat"
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 06cb55040..c516c4697 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -35,6 +35,7 @@
<!-- The workspace contains 5 screens of cells -->
<!-- DO NOT CHANGE THE ID -->
<com.android.launcher3.Workspace
+ android:theme="@style/HomeScreenElementTheme"
android:layout_gravity="center"
android:id="@+id/workspace"
android:layout_width="match_parent"
@@ -42,6 +43,8 @@
launcher:pageIndicator="@id/page_indicator">
</com.android.launcher3.Workspace>
+ <include layout="@layout/gradient_scrim" />
+
<!-- DO NOT CHANGE THE ID -->
<include layout="@layout/hotseat"
android:id="@+id/hotseat"
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index d6bdac2f0..f3539dcfa 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -59,38 +59,16 @@
<!-- Fast scroller popup -->
<TextView
style="@style/FastScrollerPopup"
- android:layout_below="@+id/search_container"
+ android:layout_alignTop="@+id/apps_list_view"
android:id="@+id/fast_scroller_popup"
android:layout_alignParentEnd="true"
android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
- <FrameLayout
- android:id="@+id/search_container"
- android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_search_bar_height"
- android:layout_gravity="center|top"
- android:gravity="center|bottom"
- android:orientation="horizontal"
- android:saveEnabled="false">
-
- <com.android.launcher3.ExtendedEditText
- android:id="@+id/search_box_input"
- android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_search_bar_field_height"
- android:background="@android:color/transparent"
- android:layout_gravity="bottom"
- android:focusableInTouchMode="true"
- android:gravity="center"
- android:imeOptions="actionSearch|flagNoExtractUi"
- android:inputType="text|textNoSuggestions|textCapWords"
- android:maxLines="1"
- android:scrollHorizontally="true"
- android:singleLine="true"
- android:textColor="?android:attr/textColorSecondary"
- android:hint="@string/all_apps_search_bar_hint"
- android:textColorHint="@drawable/all_apps_search_hint"
- android:textSize="16sp" />
- </FrameLayout>
+ <!-- Note: we are reusing/repurposing a system attribute for search layout, because of a
+ platform bug, which prevents using custom attributes in <include> tag -->
+ <include
+ layout="?android:attr/keyboardLayout"
+ android:id="@+id/search_container" />
</com.android.launcher3.allapps.AllAppsRecyclerViewContainerView>
<View
diff --git a/res/layout/all_apps_search_container.xml b/res/layout/all_apps_search_container.xml
new file mode 100644
index 000000000..c79360f66
--- /dev/null
+++ b/res/layout/all_apps_search_container.xml
@@ -0,0 +1,42 @@
+<?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.allapps.search.AppsSearchContainerLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/search_container"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/all_apps_search_bar_height"
+ android:layout_gravity="center|top"
+ android:gravity="center|bottom"
+ android:saveEnabled="false">
+
+ <com.android.launcher3.ExtendedEditText
+ android:id="@+id/search_box_input"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/all_apps_search_bar_field_height"
+ android:layout_gravity="bottom"
+ android:background="@android:color/transparent"
+ android:focusableInTouchMode="true"
+ android:gravity="center"
+ android:hint="@string/all_apps_search_bar_hint"
+ android:imeOptions="actionSearch|flagNoExtractUi"
+ android:inputType="text|textNoSuggestions|textCapWords"
+ android:maxLines="1"
+ android:scrollHorizontally="true"
+ android:singleLine="true"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textColorHint="@drawable/all_apps_search_hint"
+ android:textSize="16sp" />
+</com.android.launcher3.allapps.search.AppsSearchContainerLayout> \ No newline at end of file
diff --git a/res/layout/drop_target_bar_horz.xml b/res/layout/drop_target_bar_horz.xml
index ee22d1e74..ed18192c5 100644
--- a/res/layout/drop_target_bar_horz.xml
+++ b/res/layout/drop_target_bar_horz.xml
@@ -17,8 +17,10 @@
<com.android.launcher3.DropTargetBar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:theme="@style/HomeScreenElementTheme"
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_drop_target_size"
+ android:visibility="invisible"
android:layout_gravity="center_horizontal|top"
android:focusable="false">
diff --git a/res/layout/drop_target_bar_vert.xml b/res/layout/drop_target_bar_vert.xml
index 10b1d7cc8..e2a65d4a5 100644
--- a/res/layout/drop_target_bar_vert.xml
+++ b/res/layout/drop_target_bar_vert.xml
@@ -15,11 +15,13 @@
limitations under the License.
-->
<com.android.launcher3.DropTargetBar
+ android:theme="@style/HomeScreenElementTheme"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dynamic_grid_drop_target_size"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_gravity="left"
+ android:visibility="invisible"
android:focusable="false"
android:paddingTop="@dimen/vert_drop_target_vertical_gap" >
diff --git a/res/layout/gradient_scrim.xml b/res/layout/gradient_scrim.xml
new file mode 100644
index 000000000..c40c5fc0c
--- /dev/null
+++ b/res/layout/gradient_scrim.xml
@@ -0,0 +1,31 @@
+<?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"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <com.android.launcher3.graphics.GradientView
+ android:id="@+id/gradient_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ app:layout_ignoreInsets="true"/>
+
+ <com.android.launcher3.graphics.ScrimView
+ android:id="@+id/scrim_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ app:layout_ignoreInsets="true"/>
+</merge> \ No newline at end of file
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index f5b5bbf71..582a83fbe 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -14,6 +14,7 @@
limitations under the License.
-->
<com.android.launcher3.Hotseat
+ android:theme="@style/HomeScreenElementTheme"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto">
<com.android.launcher3.CellLayout
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index 209172143..78a0f1596 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -14,8 +14,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:theme="@style/HomeScreenElementTheme"
launcher:layout_ignoreInsets="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 2e1b57f56..e29e5b162 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -16,6 +16,7 @@
<com.android.launcher3.pageindicators.PageIndicatorLineCaret
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@style/HomeScreenElementTheme"
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_page_indicator_height">
<ImageView
diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml
index 83ad9f291..095270336 100644
--- a/res/layout/system_shortcut.xml
+++ b/res/layout/system_shortcut.xml
@@ -15,6 +15,7 @@
-->
<com.android.launcher3.shortcuts.DeepShortcutView
+ android:theme="@style/IconWithTextSystemShortcut"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/bg_popup_item_width"
diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml
index 313c69c69..2b58b92ee 100644
--- a/res/layout/system_shortcut_icon_only.xml
+++ b/res/layout/system_shortcut_icon_only.xml
@@ -16,6 +16,7 @@
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@style/IconOnlySystemShortcut"
android:layout_width="@dimen/system_shortcut_header_icon_touch_size"
android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
android:background="?android:attr/selectableItemBackgroundBorderless"
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml
index 2f11c285d..476901d1e 100644
--- a/res/layout/widgets_view.xml
+++ b/res/layout/widgets_view.xml
@@ -51,7 +51,6 @@
<!-- Fast scroller popup -->
<TextView
style="@style/FastScrollerPopup"
- android:layout_below="@+id/search_container"
android:id="@+id/fast_scroller_popup"
android:layout_gravity="top|end"
android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
diff --git a/res/raw/downgrade_schema.json b/res/raw/downgrade_schema.json
new file mode 100644
index 000000000..3c1b64f92
--- /dev/null
+++ b/res/raw/downgrade_schema.json
@@ -0,0 +1,20 @@
+{
+ // Note: Comments are not supported in JSON schema, but android parser is lenient.
+
+ // Maximum DB version supported by this schema
+ "version" : 27,
+
+ // Downgrade from 27 to 26. Empty array indicates, the DB is compatible
+ "downgrade_to_26" : [],
+ "downgrade_to_25" : [],
+ "downgrade_to_24" : [],
+ "downgrade_to_23" : [],
+ "downgrade_to_22" : [
+ "ALTER TABLE favorites RENAME TO temp_favorites;",
+ "CREATE TABLE favorites(_id INTEGER PRIMARY KEY, title TEXT, intent TEXT, container INTEGER, screen INTEGER, cellX INTEGER, cellY INTEGER, spanX INTEGER, spanY INTEGER, itemType INTEGER, appWidgetId INTEGER NOT NULL DEFAULT - 1, iconPackage TEXT, iconResource TEXT, icon BLOB, appWidgetProvider TEXT, modified INTEGER NOT NULL DEFAULT 0, restored INTEGER NOT NULL DEFAULT 0, profileId INTEGER DEFAULT 0, rank INTEGER NOT NULL DEFAULT 0);",
+ "INSERT INTO favorites SELECT _id, title, intent, container, screen, cellX, cellY, spanX, spanY, itemType, appWidgetId, iconPackage, iconResource, icon, appWidgetProvider, modified, restored, profileId, rank FROM temp_favorites;",
+ "DROP TABLE temp_favorites;"
+ ]
+
+ // Missing values indicate the DB is not compatible
+} \ No newline at end of file
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
new file mode 100644
index 000000000..5cbe40852
--- /dev/null
+++ b/res/values-az/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"İş"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Tətbiq quraşdırılmayıb."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Tətbiq əlçatmazdır"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Güvənli rejimdə icazə verilməyən tətbiq endirildi"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Vidcetlər Güvənli rejimdə deaktiv edilib"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Qısayol əlçatan deyil"</string>
+ <string name="home_screen" msgid="806512411299847073">"Əsas ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Fərdi əməliyyatlar"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidceti götürmək üçün toxunub saxlayın."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Vidceti götürmək üçün &amp; 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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manual olaraq yerləşdirmək üçün toxunaraq basıb saxlayın"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Avtomatik əlavə edin"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Bu Əsas ekranda boş yer yoxdur."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritlər-də yer yoxdur"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Tətbiq siyahısı"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Əsas səhifə"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Silin"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Sistemdən sil"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Tətbiq məlumatı"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"qısayolları quraşdır"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Tətbiqə istifadəçi müdaxiləsi olmadan qısayolları əlavə etməyə icazə verir."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"Əsas Səhifə ayarlarını və qısayolları oxuyun"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Tətbiqə Əsas Səhifədə parametrləri və qısayolları oxumağa icazə verir."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"Əsas Səhifə ayarlarını və qısayolları yazın"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Tətbiqə Əsas Səhifədə ayarları və qısayolları dəyişməyə icazə verir."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə telefon zəngləri etmək üçün icazə verilmir"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Vidcet yükləmə problemi"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Quraşdırma"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu sistem tətbiqi olduğu üçün sistemdən silinə bilməz."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Adsız Qovluq"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> deaktiv edildi"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Səhifə %1$d of %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Əsas Səhifə ekranı %1$d of %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Yeni əsas ekran səhifəsi"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Qovluq açıldı, <xliff:g id="HEIGHT">%2$d</xliff:g> hündürlük ilə <xliff:g id="WIDTH">%1$d</xliff:g> enində"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Qovluq bağlamaq üçün toxunun"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ad dəyişikliyini yadda saxlamaq üçün toxunun"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Qovluq bağlıdır"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Qovluq adı <xliff:g id="NAME">%1$s</xliff:g> ilə dəyişdirildi"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidcet"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Ayarlar"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"İcmal"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Bu tətbiq quraşdırılmayıb"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Bu ikona üçün tətbiq quraşdırılmayıb. Onu silə bilərsiniz, və ya tətbiqi taparaq manual yol ilə quraşdıra bilərsiniz."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> endirilir, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> yüklənmək üçün gözləyir"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> vidcetləri"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Əsas ekrana əlavə edin"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Elementi bura köçürün"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Element əsas ekrana əlavə edildi"</string>
+ <string name="item_removed" msgid="851119963877842327">"Element silindi"</string>
+ <string name="action_move" msgid="4339390619886385032">"Elementi köçürün"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Sıra <xliff:g id="NUMBER_0">%1$s</xliff:g> sütun <xliff:g id="NUMBER_1">%2$s</xliff:g> köçürün"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> mövqeyinə köçürün"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"<xliff:g id="NUMBER">%1$s</xliff:g> sevimlilər mövqeyinə köçürün"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Elementin yeri dəyişildi"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Qovluğa əlavə edin: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> adlı qovluğa əlavə edin"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Element qovluğa əlavə edildi"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Qovluq yaradın: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Qovluq yaradıldı"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Əsas ekrana köçürün"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Ekranı sola köçürün"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Ekranı sağa köçürün"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Ekran köçürülüb"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Ölçüsünü dəyişin"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Eni artırın"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Hündürlüyü artırın"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Eni azaldın"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Hündürlüyü azaldın"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Vidcetin eni <xliff:g id="NUMBER_0">%1$s</xliff:g> hündürlüyü <xliff:g id="NUMBER_1">%2$s</xliff:g> kimi ölçüləndirildi"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Qısa yollar"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> üçün <xliff:g id="APP_NAME">%2$s</xliff:g> qısa yolu"</string>
+</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index fc5390b80..8eb7e8423 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -19,188 +19,103 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for application_name (5181331383435256801) -->
- <skip />
- <!-- no translation found for home (7658288663002113681) -->
- <skip />
- <!-- no translation found for uid_name (7820867637514617527) -->
- <skip />
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
- <!-- no translation found for wallpaper_instructions (563973358787555519) -->
- <skip />
- <!-- no translation found for image_load_fail (2821429163328561136) -->
- <skip />
- <!-- no translation found for wallpaper_load_fail (1261270681127096352) -->
- <skip />
- <!-- no translation found for number_of_items_selected:zero (7464587177007785408) -->
- <!-- no translation found for number_of_items_selected:one (142482526010824029) -->
- <!-- no translation found for number_of_items_selected:other (1418352074806573570) -->
- <!-- no translation found for wallpaper_accessibility_name (1655953108132967972) -->
- <skip />
- <!-- no translation found for announce_selection (8338254712932127413) -->
- <skip />
- <!-- no translation found for wallpaper_delete (8095005658756613921) -->
- <skip />
- <!-- no translation found for pick_image (1272073934062909527) -->
- <skip />
- <!-- no translation found for pick_wallpaper (8179698221502010609) -->
- <skip />
- <!-- no translation found for crop_wallpaper (8334345984491368009) -->
- <skip />
- <!-- no translation found for activity_not_found (8071924732094499514) -->
- <skip />
- <!-- no translation found for widgets_tab_label (2921133187116603919) -->
- <skip />
- <!-- no translation found for widget_adder (3201040140710381657) -->
- <skip />
- <!-- no translation found for toggle_weight_watcher (5645299835184636119) -->
- <skip />
- <!-- no translation found for long_press_widget_to_add (7699152356777458215) -->
- <skip />
- <!-- no translation found for market (2619650989819296998) -->
- <skip />
- <!-- no translation found for widget_dims_format (2370757736025621599) -->
- <skip />
- <!-- no translation found for external_drop_widget_error (3165821058322217155) -->
- <skip />
- <!-- no translation found for external_drop_widget_pick_title (3486317258037690630) -->
- <skip />
- <!-- no translation found for rename_folder_label (3727762225964550653) -->
- <skip />
- <!-- no translation found for rename_folder_title (3771389277707820891) -->
- <skip />
- <!-- no translation found for rename_action (5559600076028658757) -->
- <skip />
- <!-- no translation found for cancel_action (7009134900002915310) -->
- <skip />
- <!-- no translation found for menu_item_add_item (1264911265836810421) -->
- <skip />
- <!-- no translation found for group_applications (3797214114206693605) -->
- <skip />
- <!-- no translation found for group_shortcuts (6012256992764410535) -->
- <skip />
- <!-- no translation found for group_widgets (1569030723286851002) -->
- <skip />
- <!-- no translation found for completely_out_of_space (6106288382070760318) -->
- <skip />
- <!-- no translation found for out_of_space (4691004494942118364) -->
- <skip />
- <!-- no translation found for hotseat_out_of_space (9139760413395605841) -->
- <skip />
- <!-- no translation found for invalid_hotseat_item (1211534262129849507) -->
- <skip />
- <!-- no translation found for shortcut_installed (1701742129426969556) -->
- <skip />
- <!-- no translation found for shortcut_uninstalled (8176767991305701821) -->
- <skip />
- <!-- no translation found for shortcut_duplicate (9167217446062498127) -->
- <skip />
- <!-- no translation found for title_select_shortcut (6680642571148153868) -->
- <skip />
- <!-- no translation found for title_select_application (3280812711670683644) -->
- <skip />
- <!-- no translation found for all_apps_button_label (9110807029020582876) -->
- <skip />
- <!-- no translation found for all_apps_home_button_label (252062713717058851) -->
- <skip />
- <!-- no translation found for delete_zone_label_workspace (4009607676751398685) -->
- <skip />
- <!-- no translation found for delete_zone_label_all_apps (8083826390278958980) -->
- <skip />
- <!-- no translation found for delete_target_label (1822697352535677073) -->
- <skip />
- <!-- no translation found for delete_target_uninstall_label (5100785476250872595) -->
- <skip />
- <!-- no translation found for info_target_label (8053346143994679532) -->
- <skip />
- <!-- no translation found for accessibility_search_button (1628520399424565142) -->
- <skip />
- <!-- no translation found for accessibility_voice_search_button (4637324840434406584) -->
- <skip />
- <!-- no translation found for accessibility_all_apps_button (2603132375383800483) -->
- <skip />
- <!-- no translation found for accessibility_delete_button (6466114477993744621) -->
- <skip />
- <!-- no translation found for delete_zone_label_all_apps_system_app (449755632749610895) -->
- <skip />
- <!-- no translation found for cab_menu_delete_app (7435191475867183689) -->
- <skip />
- <!-- no translation found for cab_menu_app_info (8593722221450362342) -->
- <skip />
- <!-- no translation found for cab_app_selection_text (374688303047985416) -->
- <skip />
- <!-- no translation found for cab_widget_selection_text (1833458597831541241) -->
- <skip />
- <!-- no translation found for cab_folder_selection_text (7999992513806132118) -->
- <skip />
- <!-- no translation found for cab_shortcut_selection_text (2103811025667946450) -->
- <skip />
- <!-- no translation found for permlab_install_shortcut (5632423390354674437) -->
- <skip />
- <!-- no translation found for permdesc_install_shortcut (923466509822011139) -->
- <skip />
- <!-- no translation found for permlab_uninstall_shortcut (864595034498083837) -->
- <skip />
- <!-- no translation found for permdesc_uninstall_shortcut (5134129545001836849) -->
- <skip />
- <!-- no translation found for permlab_read_settings (1941457408239617576) -->
- <skip />
- <!-- no translation found for permdesc_read_settings (5833423719057558387) -->
- <skip />
- <!-- no translation found for permlab_write_settings (3574213698004620587) -->
- <skip />
- <!-- no translation found for permdesc_write_settings (5440712911516509985) -->
- <skip />
- <!-- no translation found for gadget_error_text (6081085226050792095) -->
- <skip />
- <!-- no translation found for uninstall_system_app_text (4172046090762920660) -->
- <skip />
- <!-- no translation found for dream_name (1530253749244328964) -->
- <skip />
- <!-- no translation found for folder_hint_text (6617836969016293992) -->
- <skip />
- <!-- no translation found for workspace_description_format (2950174241104043327) -->
- <skip />
- <!-- no translation found for default_scroll_format (7475544710230993317) -->
- <skip />
- <!-- no translation found for workspace_scroll_format (8458889198184077399) -->
- <skip />
- <!-- no translation found for apps_customize_apps_scroll_format (370005296147130238) -->
- <skip />
- <!-- no translation found for apps_customize_widgets_scroll_format (3106209519974971521) -->
- <skip />
- <!-- no translation found for first_run_cling_title (7257389003637362144) -->
- <skip />
- <!-- no translation found for first_run_cling_description (6447072552696253358) -->
- <skip />
- <!-- no translation found for first_run_cling_create_screens_hint (6950729526680114157) -->
- <skip />
- <!-- no translation found for workspace_cling_title (5626202359865825661) -->
- <skip />
- <!-- no translation found for workspace_cling_move_item (528201129978005352) -->
- <skip />
- <!-- no translation found for folder_cling_title (3894908818693254164) -->
- <skip />
- <!-- no translation found for folder_cling_create_folder (6158215559475836131) -->
- <skip />
- <!-- no translation found for cling_dismiss (8962359497601507581) -->
- <skip />
- <!-- no translation found for folder_opened (94695026776264709) -->
- <skip />
- <!-- no translation found for folder_tap_to_close (1884479294466410023) -->
- <skip />
- <!-- no translation found for folder_tap_to_rename (9191075570492871147) -->
- <skip />
- <!-- no translation found for folder_closed (4100806530910930934) -->
- <skip />
- <!-- no translation found for folder_renamed (1794088362165669656) -->
- <skip />
- <!-- no translation found for folder_name_format (6629239338071103179) -->
- <skip />
- <!-- no translation found for widget_button_text (2880537293434387943) -->
- <skip />
- <!-- no translation found for wallpaper_button_text (8404103075899945851) -->
- <skip />
- <!-- no translation found for settings_button_text (8119458837558863227) -->
- <skip />
+ <string name="work_folder_name" msgid="3753320833950115786">"Працоўная"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Праграма не ўсталявана."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Праграма недаступная"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Спампаваная праграма адключана ў Бяспечным рэжыме"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Віджэты адключаны ў Бяспечным рэжыме"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Ярлык недаступны"</string>
+ <string name="home_screen" msgid="806512411299847073">"Галоўны экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Спецыяльныя дзеянні"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Дакраніцеся і ўтрымлiвайце віджэт, каб выбр. яго."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Каб размясціць уручную, дакраніцеся і ўтрымлівайце"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Дадаць аўтаматычна"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"На гэтым Галоўным экране больш няма месца."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"У латку \"Абранае\" больш няма месца"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Спіс праграм"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Галоўная"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Выдаліць"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Выдаліць"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Звесткі пра праграму"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"усталёўваць ярлыкі"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Дазваляе праграмам дадаваць ярлыкі без умяшання карыстальніка."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"счытваць налады і ярлыкі на Галоўнай старонцы"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Дазваляе праграме счытваць налады і ярлыкі на Галоўнай старонцы."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"запісваць налады і ярлыкі на галоўнай старонцы"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Дазваляе праграме змяняць налады і ярлыкі на Галоўнай старонцы."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> не мае дазволу на здзяйсненне тэлефонных званкоў"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Праблема загрузкі віджэта"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Наладжванне"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Гэта сістэмная праграма, яе нельга выдаліць."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Папка без назвы"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> адключана"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Старонка %1$d з %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Галоўны экран %1$d з %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Новая старонка галоўнага экрана"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Папка адкрыта, <xliff:g id="WIDTH">%1$d</xliff:g> на <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Краніце, каб закрыць папку"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Краніце, каб захаваць новую назву"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Папка закрыта"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Папка перайменавана ў <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Віджэты"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Шпалеры"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Налады"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Агляд"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"Невядома"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Выдаліць"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"Шукаць"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Гэта праграма не ўсталявана"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Праграма для гэтага значка не ўсталявана. Вы можаце выдаліць яе або выканаць пошук і ўсталяваць яе ўручную."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"Ідзе спампоўка <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> завершана"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чакае ўсталёўкі"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Віджэты <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Дадаць на Галоўны экран"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Перамясціць элемент сюды"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Элемент дададзены на галоўны экран"</string>
+ <string name="item_removed" msgid="851119963877842327">"Элемент выдалены"</string>
+ <string name="action_move" msgid="4339390619886385032">"Перамясціць элемент"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Перамясціць у радок <xliff:g id="NUMBER_0">%1$s</xliff:g> слупок <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Перамясціць у пазіцыю <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Перамясціць у абранае, у пазіцыю <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Элемент перамешчаны"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Дадаць у папку: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Дадаць у папку з <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Элемент дададзены ў папку"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Стварыць папку з: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Папка створана"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Перамясціць на Галоўны экран"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Перамясціць экран налева"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Перамясціць экран направа"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Экран перамешчаны"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Змяніць памер"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Павялічыць шырыню"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Павялічыць вышыню"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Паменшыць шырыню"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Паменшыць вышыню"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Памеры віджэта зменены на: шырыня <xliff:g id="NUMBER_0">%1$s</xliff:g>, вышыня <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлыкі"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"Ярлыкі (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) для <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
</resources>
diff --git a/res/values-bn/config.xml b/res/values-bn/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-bn/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
new file mode 100644
index 000000000..065019a29
--- /dev/null
+++ b/res/values-bn/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"কাজ"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"অ্যাপ্লিকেশান ইনস্টল করা নেই৷"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"অ্যাপ্লিকেশান অনুপলব্ধ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনলোড করা অ্যাপ্লিকেশান নিরাপদ মোডে অক্ষম রয়েছে"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"সুরক্ষিত মোডে উইজেট নিষ্ক্রিয় থাকে"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"শর্টকাটগুলি অনুপলব্ধ"</string>
+ <string name="home_screen" msgid="806512411299847073">"হোম স্ক্রীন"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"কাস্টম অ্যাকশন"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"নিজে যোগ করতে টাচ করে ধরে রাখুন"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্রিয়ভাবে যোগ করুন"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"আরো অ্যাপ্লিকেশানের জন্য অনুসন্ধান করুন"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"এই হোম স্ক্রীনে আর কোনো জায়গা নেই৷"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"পছন্দসই ট্রে-তে আর কোনো জায়গা নেই"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"অ্যাপ্লিকেশানগুলির তালিকা"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"হোম"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"সরান"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"আনইনস্টল করুন"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"অ্যাপ্লিকেশানের তথ্য"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"শর্টকাটগুলি ইনস্টল করে"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"হোম সেটিংস এবং শর্টকাটগুলি পড়ে"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পড়তে দেয়৷"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"হোম সেটিংস এবং শর্টকাটগুলি লেখে"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পরিবর্তন করতে দেয়৷"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"ফোন কলগুলি করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g> এর অনুমতি নেই"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"উইজেট লোড হতে সমস্যা হয়েছে"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"সেটআপ"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"এটি একটি সিস্টেম অ্যাপ্লিকেশান এবং আনইনস্টল করা যাবে না৷"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম করা হয়েছে"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$dটির মধ্যে %1$dটি পৃষ্ঠা"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dটির %1$d নম্বর হোম স্ক্রীন"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"নতুন হোম স্ক্রীনের পৃষ্ঠা"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ফোল্ডার খোলা হয়েছে, <xliff:g id="WIDTH">%1$d</xliff:g> বাই <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ফোল্ডার বন্ধ করতে আলতো চাপ দিন"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"পুনঃনামকরণ সংরক্ষণ করতে আলতো চাপ দিন"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ফোল্ডার বন্ধ করা হয়েছে"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ফোল্ডারের নাম পাল্টে <xliff:g id="NAME">%1$s</xliff:g> করা হয়েছে"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"উইজেটগুলি"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"সেটিংস"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"এক নজরে"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"আইকনের আকৃতি পরিবর্তন করুন"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"পরিবর্তন করবেন না"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"আইকনের আকৃতি পরিবর্তন করা হচ্ছে"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"অজানা"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"সরান"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"অনুসন্ধান"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"এই অ্যাপ্লিকেশানটি ইন্সটল করা নাই"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"এই আইকনের অ্যাপ্লিকেশানটি ইন্সটল করা নাই। আপনি এটি সরাতে পারেন বা অ্যাপ্লিকেশানটি অনুসন্ধান করে এটি নিজে ইন্সটল করতে পারেন।"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনলোড হচ্ছে <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পন্ন হয়েছে"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ইনস্টলের অপেক্ষায় রয়েছে"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> উইজেট"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"হোম স্ক্রীনে যোগ করুন"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"এখানে আইটেম সরান"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"হোম স্ক্রীনে আইটেম যোগ করা হয়েছে"</string>
+ <string name="item_removed" msgid="851119963877842327">"আইটেম সরানো হয়েছে"</string>
+ <string name="action_move" msgid="4339390619886385032">"আইটেম সরান"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"সারি <xliff:g id="NUMBER_0">%1$s</xliff:g> কলাম <xliff:g id="NUMBER_1">%2$s</xliff:g> এ সরান"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"অবস্থানে সরান <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"পছন্দসই অবস্থানে সরান <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"আইটেম সরানো হয়েছে"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ফোল্ডারে যোগ করুন: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> সহ ফোল্ডারে যোগ করা হয়েছে"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"আইটেম ফোল্ডারে যোগ করা হয়েছে"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"এর সাথে ফোল্ডার তৈরি করুন: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ফোল্ডার তৈরি করা হয়েছে"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"হোম স্ক্রীনে সরান"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"স্ক্রীন বাঁ দিকে সরান"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"স্ক্রীন ডান দিকে সরান"</string>
+ <string name="screen_moved" msgid="266230079505650577">"স্ক্রীন সরানো হয়েছে"</string>
+ <string name="action_resize" msgid="1802976324781771067">"আবার আকার দিন"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"প্রস্থ বাড়ান"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"উচ্চতা বাড়ান"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"প্রস্থ কমান"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"উচ্চতা কমান"</string>
+ <string name="widget_resized" msgid="9130327887929620">"উইজেটের আকার প্রস্থ <xliff:g id="NUMBER_0">%1$s</xliff:g> উচ্চতা <xliff:g id="NUMBER_1">%2$s</xliff:g> তে পরিবর্তন করা হয়েছে"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"শর্টকাট"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> এর <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>টি শর্টকার্ট"</string>
+</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
new file mode 100644
index 000000000..8e1234edc
--- /dev/null
+++ b/res/values-bs/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Posao"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija je onemogućena u sigurnom načinu rada"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Vidžeti su onemogućeni u sigurnom načinu rada."</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Prečica nije dostupna"</string>
+ <string name="home_screen" msgid="806512411299847073">"Početni ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Prilagođene akcije"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite &amp; i držite da biste uzeli dodatak."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvaput dodirnite &amp; i držite da biste uzeli vidžet ili koristite prilagođene radnje."</string>
+ <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, visina %2$d"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i držite da postavite ručno"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
+ <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretraži aplikacije"</string>
+ <string name="all_apps_loading_message" msgid="7557140873644765180">"Aplikacije se učitavaju…"</string>
+ <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nije pronađena nijedna aplikacija koja odgovara upitu \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži više aplikacija"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom ekranu nema više prostora."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Nema više prostora u ladici Favoriti"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Spisak aplikacija"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Tipka za početak"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Ukloni"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstaliraj"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Informacije o aplikaciji"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliraj prečice"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Dopušta aplikaciji dodavanje prečica bez posredovanja korisnika."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"čitaj postavke na početnom ekranu i prečice"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Dopušta aplikaciji čitanje postavki i prečica na početnom ekranu."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"zapisuj postavke na početnom ekranu i prečice"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Dopušta aplikaciji promjenu postavki i prečica na početnom ekranu."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nema dozvolu da uspostavlja telefonske pozive"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju dodatka"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Postavljanje"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je sistemska aplikacija i ne može se deinstalirati."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana fascikla"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućena"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Strana %1$d od %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Početni ekran %1$d od %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Nova stranica početnog ekrana"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Fascikla je otvorena, (š) <xliff:g id="WIDTH">%1$d</xliff:g> (v) <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Dodirnite da zatvorite folder"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Dodirnite da sačuvate promjenu imena"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Fascikla je zatvorena"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Ime fascikle je promijenjeno u <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Fascikla: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Dodaci"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Postavke"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Pregled"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotiranje početnog ekrana"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zarotira"</string>
+ <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutne postavke ekrana ne dozvoljavaju rotiranje"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodajte ikonu na početni ekran"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Ova aplikacija nije instalirana"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacija za ovu ikonu nije instalirana. Možete je ukloniti ili potražiti aplikaciju i ručno je instalirati."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se preuzima, završeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> čeka da se instalira"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Vidžeti za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Dodaj na početni ekran"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Premjesti stavku ovdje"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Stavka je dodana na Početni ekran."</string>
+ <string name="item_removed" msgid="851119963877842327">"Stavka je uklonjena"</string>
+ <string name="action_move" msgid="4339390619886385032">"Premjesti stavku"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Pomjeri stavku u red <xliff:g id="NUMBER_0">%1$s</xliff:g> kolonu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Pomjeri stavku na poziciju <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Pomjeri stavku na poziciju <xliff:g id="NUMBER">%1$s</xliff:g> među favoritima"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Stavka je premještena"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Dodaj u folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Dodaj u folder sa aplikacijom <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Stavka je dodana u folder"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Kreirajte folder sa stavkom: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Folder je kreiran"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Pomjeri na početni ekran"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Pomjeri ekran ulijevo"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Pomjeri ekran udesno"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Ekran je pomjeren"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Promijeni veličinu"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Povećaj širinu"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Povećaj visinu"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Smanji širinu"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Smanji visinu"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Veličina vidžeta je promijenjena na širinu <xliff:g id="NUMBER_0">%1$s</xliff:g> visinu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Prečice"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> prečica za aplikaciju <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index afed3b548..91a733318 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -19,35 +19,103 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="application_name" msgid="8424725141379931883">"Käivitaja"</string>
- <string name="folder_name" msgid="8551881338202938211"></string>
- <string name="wallpaper_instructions" msgid="4215640646180727542">"Määra taustapilt"</string>
- <string name="pick_wallpaper" msgid="5630222540525626723">"Taustapildid"</string>
- <string name="activity_not_found" msgid="217823393239365967">"Rakendus pole installitud."</string>
- <string name="long_press_widget_to_add" msgid="7395697462851217506">"Vidina valimiseks puudutage seda pikalt."</string>
- <string name="widget_dims_format" msgid="1386418557719032947">"%1$d × %2$d"</string>
- <string name="out_of_space" msgid="8365249326091984698">"Sellel avalehel pole enam ruumi."</string>
- <string name="hotseat_out_of_space" msgid="6304886797358479361">"Kohandataval dokialal pole rohkem ruumi."</string>
- <string name="all_apps_button_label" msgid="2578400570124163469">"Rakendused"</string>
- <string name="all_apps_home_button_label" msgid="1022222300329398558">"Kodu"</string>
- <string name="delete_target_label" msgid="665300185123139530">"Eemalda"</string>
- <string name="delete_target_uninstall_label" msgid="748894921183769150">"Desinstalli"</string>
- <string name="info_target_label" msgid="4019495079517426980">"Rakenduse teave"</string>
- <string name="permlab_install_shortcut" msgid="1201690825493376489">"otseteede installimine"</string>
- <string name="permdesc_install_shortcut" msgid="8634424803272077038">"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."</string>
- <string name="permlab_read_settings" msgid="3452408290738106747">"avalehe seadete ja otseteede lugemine"</string>
- <string name="permdesc_read_settings" msgid="5788109303585403679">"Võimaldab rakendusel lugeda avalehe seadeid ja otseteid."</string>
- <string name="permlab_write_settings" msgid="1360567537236705628">"avalehe seadete ja otseteede kirjutamine"</string>
- <string name="permdesc_write_settings" msgid="8530105489115785531">"Võimaldab rakendusel muuta avalehel seadeid ja otseteid."</string>
- <string name="gadget_error_text" msgid="8359351016167075858">"Probleem vidina laadimisel"</string>
- <string name="uninstall_system_app_text" msgid="6429814133777046491">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
- <string name="folder_hint_text" msgid="8633351560105748141">"Nimeta kaust"</string>
- <string name="default_scroll_format" msgid="4057140866420001240">"Leht %1$d/%2$d"</string>
- <string name="workspace_scroll_format" msgid="1704767047951143301">"Avakuva %1$d/%2$d"</string>
- <string name="folder_opened" msgid="1262064100943801533">"Kaust on avatud, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="1335478160661137579">"Puudutage kausta sulgemiseks"</string>
- <string name="folder_tap_to_rename" msgid="5201612989905472442">"Puudutage uue nime salvestamiseks"</string>
- <string name="folder_closed" msgid="3130534551370511932">"Kaust suletud"</string>
- <string name="folder_renamed" msgid="7951233572858053642">"Kausta uus nimi: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format" msgid="3051680259794759037">"<xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Töö"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Rakendus ei ole saadaval"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Allalaetud rakendus on turvarežiimis keelatud"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Turvarežiimis on vidinad keelatud"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Otsetee pole saadaval"</string>
+ <string name="home_screen" msgid="806512411299847073">"Avaekraan"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Kohandatud toimingud"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidina valimiseks vajutage ja hoidke seda all."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Puudutage pikalt, et käsitsi asetada"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Lisa 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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Sellel avaekraanil pole enam ruumi."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Salves Lemmikud pole rohkem ruumi"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Rakenduste loend"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Avaekraan"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Eemalda"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalli"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Rakenduse teave"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"installi otseteed"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"loe avaekraani seadeid ja otseteid"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Võimaldab rakendusel lugeda avaekraanil seadeid ja otseteid."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"kirjuta avaekraani seaded ja otseteed"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"Rakendusel <xliff:g id="APP_NAME">%1$s</xliff:g> pole lubatud helistada"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Probleem vidina laadimisel"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Seadistamine"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Nimetu kaust"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on keelatud"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Leht %1$d/%2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Avaekraan %1$d/%2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Uus avaekraan"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Kaust on avatud, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Puudutage kausta sulgemiseks"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Puudutage ümbernimetamise salvestamiseks"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Kaust on suletud"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Kausta uus nimi: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidinad"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Seaded"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Ülevaade"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"See rakendus ei ole installitud"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Selle ikooni rakendust pole installitud. Saate selle eemaldada või rakendust otsida ja käsitsi installida."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> allalaadimine, <xliff:g id="PROGRESS">%2$s</xliff:g> on valmis"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> on installimise ootel"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Teenuse <xliff:g id="NAME">%1$s</xliff:g> vidinad"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Lisa avaekraanile"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Teisalda üksus siia"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Üksus lisati avaekraanile"</string>
+ <string name="item_removed" msgid="851119963877842327">"Üksus eemaldati"</string>
+ <string name="action_move" msgid="4339390619886385032">"Teisalda üksus"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Teisaldamine <xliff:g id="NUMBER_0">%1$s</xliff:g>. rea <xliff:g id="NUMBER_1">%2$s</xliff:g>. veergu"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Teisaldamine <xliff:g id="NUMBER">%1$s</xliff:g>. positsioonile"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Teisaldamine lemmikute <xliff:g id="NUMBER">%1$s</xliff:g>. positsioonile"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Üksus teisaldati"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Lisamine kausta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Lisamine kausta nimega <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Üksus lisati kausta"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Kausta loomine nimega <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Kaust on loodud"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Teisalda avaekraanile"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Teisalda ekraan vasakule"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Teisalda ekraan paremale"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Ekraan teisaldati"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Muuda suurust"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Suurenda laiust"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Suurenda kõrgust"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Vähenda laiust"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Vähenda kõrgust"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Vidina suurust muudeti. Laius: <xliff:g id="NUMBER_0">%1$s</xliff:g>. Kõrgus: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Otseteed"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> otseteed rakenduse <xliff:g id="APP_NAME">%2$s</xliff:g> jaoks"</string>
</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
new file mode 100644
index 000000000..1a4d80943
--- /dev/null
+++ b/res/values-eu/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Lana"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Aplikazioa instalatu gabe dago."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Ez dago erabilgarri aplikazioa"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Deskargatutako aplikazioa modu seguruan desgaitu da"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Lasterbideak ez daude erabilgarri"</string>
+ <string name="home_screen" msgid="806512411299847073">"Hasierako pantaila"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Ekintza pertsonalizatuak"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Eduki sakatuta widgeta aukeratzeko."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Eduki sakatuta eskuz gehitzeko"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Gehitu 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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Hasierako pantaila honetan ez dago toki gehiago."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ez dago toki gehiago Gogokoak erretiluan"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Aplikazioen zerrenda"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Hasiera"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Kendu"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalatu"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Aplikazioaren datuak"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"Instalatu lasterbideak"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Erabiltzaileak ezer egin gabe lasterbideak gehitzea baimentzen die aplikazioei."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"Irakurri hasierako ezarpenak eta lasterbideak"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Hasierako pantailako ezarpenak eta lasterbideak irakurtzea baimentzen die aplikazioei."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"Idatzi hasierako ezarpenak eta lasterbideak"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez du telefono-deiak egiteko baimenik"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Arazo bat izan da widgeta kargatzean"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurazioa"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Sistema-aplikazioa da hau eta ezin da desinstalatu."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Izenik gabeko karpeta"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desgaituta dago"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%1$d/%2$d orria"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d/%2$d hasierako pantaila"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Hasierako pantailaren orri berria"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Karpeta ireki da: <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Karpeta ixteko, sakatu hau"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Izen berria gordetzeko, sakatu hau"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Karpeta itxi da"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Karpetari <xliff:g id="NAME">%1$s</xliff:g> izena eman zaio"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Karpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgetak"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Ezarpenak"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Ikuspegi orokorra"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikazio hau ez dago instalatuta"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ikono honen aplikazioa ez dago instalatuta. Ikonoa ken dezakezu, edo aplikazioa bilatu eta eskuz instalatu."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> deskargatzen, <xliff:g id="PROGRESS">%2$s</xliff:g> osatuta"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> instalatzeko zain"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgetak"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Gehitu hasierako pantailan"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Ekarri elementua hona"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Gehitu da elementua hasierako pantailan"</string>
+ <string name="item_removed" msgid="851119963877842327">"Kendu da elementua"</string>
+ <string name="action_move" msgid="4339390619886385032">"Mugitu elementua"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Eraman <xliff:g id="NUMBER_0">%1$s</xliff:g>. errenkadara, <xliff:g id="NUMBER_1">%2$s</xliff:g>. zutabera"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Eraman <xliff:g id="NUMBER">%1$s</xliff:g>. postura"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Eraman gogokoen <xliff:g id="NUMBER">%1$s</xliff:g>. postura"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Elementua mugitu da"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Gehitu <xliff:g id="NAME">%1$s</xliff:g> karpetan"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Gehitu <xliff:g id="NAME">%1$s</xliff:g> duen karpetan"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Elementua karpetan gehitu da"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Sortu karpeta <xliff:g id="NAME">%1$s</xliff:g> elementuarekin"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Karpeta sortu da"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Eraman hasierako pantailara"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Eraman pantaila ezkerrera"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Eraman pantaila eskuinera"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Mugitu da pantaila"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Aldatu tamaina"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Handitu zabalera"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Handitu altuera"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Txikitu zabalera"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Txikitu altuera"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Aldatu da widgetaren tamaina. Zabalera: <xliff:g id="NUMBER_0">%1$s</xliff:g>. Altuera: <xliff:g id="NUMBER_1">%2$s</xliff:g>."</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Lasterbideak"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioaren <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> lasterbide"</string>
+</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
new file mode 100644
index 000000000..e8213b51d
--- /dev/null
+++ b/res/values-gl/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Traballo"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"A aplicación non está instalada"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"A aplicación non está dispoñible"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"A aplicación que descargaches está desactivada no modo seguro"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Os widgets están desactivados no modo seguro"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"O atallo non está dispoñible"</string>
+ <string name="home_screen" msgid="806512411299847073">"Pantalla de inicio"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Accións personalizadas"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premido un widget para seleccionalo."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén premido o elemento para colocalo manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Engadir 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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Non hai máis espazo nesta pantalla de inicio."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Non hai máis espazo na bandexa de favoritos"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicacións"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Inicio"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Eliminar"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Info. da aplicación"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atallos"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a unha aplicación engadir atallos sen intervención do usuario."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ler a configuración e os atallos da pantalla de inicio"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite a unha aplicación ler a configuración e os atallos da páxina de inicio."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"modificar a configuración e os atallos da pantalla de inicio"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite a unha aplicación cambiar a configuración e os atallos da pantalla de inicio."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> non ten permiso para facer chamadas telefónicas"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Produciuse un problema ao cargar o widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación é do sistema e non se pode desinstalar."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Cartafol sen nome"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"Desactivouse <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Páxina %1$d de %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla de inicio %1$d de %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Nova páxina da pantalla de inicio"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Abriuse o cartafol, <xliff:g id="WIDTH">%1$d</xliff:g> por <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Toca fóra para pechar o cartafol"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Toca fóra para cambiar o nome do cartafol"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Pechouse o cartafol"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"O cartafol cambiou o nome a <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Configuración"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Visión xeral"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Esta aplicación non está instalada"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"A aplicación para esta icona non está instalada. Podes eliminala ou buscar a aplicación e instalala manualmente."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"Descargando <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="PROGRESS">%2$s</xliff:g> completado)"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"Esperando para instalar <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Engadir á pantalla de inicio"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Mover elemento aquí"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Engadiuse o elemento á pantalla de inicio"</string>
+ <string name="item_removed" msgid="851119963877842327">"Eliminouse o elemento"</string>
+ <string name="action_move" msgid="4339390619886385032">"Mover elemento"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Mover á fila <xliff:g id="NUMBER_0">%1$s</xliff:g> columna <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Mover á posición <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Mover á posición dos favoritos <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Moveuse o elemento"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Engadir ao cartafol: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Engadir ao cartafol con <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Engadiuse o elemento ao cartafol"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Crear cartafol con: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Creouse o cartafol"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Mover á pantalla de inicio"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Mover pantalla á esquerda"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Mover pantalla á dereita"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Moveuse a pantalla"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Cambiar tamaño"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Aumentar ancho"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Aumentar altura"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Reducir ancho"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Reducir altura"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Cambiouse o tamaño do widget polo ancho <xliff:g id="NUMBER_0">%1$s</xliff:g> e a altura <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Atallos"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atallos para <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-gu/config.xml b/res/values-gu/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-gu/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
new file mode 100644
index 000000000..aa4992db7
--- /dev/null
+++ b/res/values-gu/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"કાર્યાલય"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"ઍપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ઍપ્લિકેશન ઉપલબ્ધ નથી"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"સુરક્ષિત મોડમાં ડાઉનલોડ કરેલ ઍપ્લિકેશન અક્ષમ કરી"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"સુરક્ષિત મોડમાં વિજેટ્સ અક્ષમ કર્યા"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"શૉર્ટકટ ઉપલબ્ધ નથી"</string>
+ <string name="home_screen" msgid="806512411299847073">"હોમ સ્ક્રીન"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"કસ્ટમ ક્રિયાઓ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"વિજેટ ચૂંટવા માટે ટચ કરો અને પકડી રાખો."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"મેન્યુઅલી મૂકવા માટે ટચ કરી દબાવી રાખો"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"આપમેળે ઉમેરો"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"સૂચનાઓ"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"મનપસંદ ટ્રે પર વધુ જગ્યા નથી"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"ઍપ્લિકેશનોની સૂચિ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"હોમ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"દૂર કરો"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"અનઇન્સ્ટોલ કરો"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ઍપ્લિકેશન માહિતી"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"હોમ સેટિંગ્સ અને શોર્ટકટ્સ વાંચો"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ વાંચવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"હોમ સેટિંગ્સ અને શોર્ટકટ્સ લખો"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ બદલવાની મંજૂરી આપે છે."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ને ફોન કૉલ્સ કરવાની મંજૂરી નથી"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"વિજેટ લોડ કરવામાં સમસ્યા"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"સેટઅપ"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"આ એક સિસ્ટમ ઍપ્લિકેશન છે અને અનઇન્સ્ટોલ કરી શકાતી નથી."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"અનામી ફોલ્ડર"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> અક્ષમ કરી"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d માંથી %1$d પૃષ્ઠ"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d માંથી %1$d હોમ સ્ક્રીન"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"નવું હોમ સ્ક્રીન પૃષ્ઠ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"<xliff:g id="WIDTH">%1$d</xliff:g> બાય <xliff:g id="HEIGHT">%2$d</xliff:g> નું ફોલ્ડર ખોલ્યું"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ફોલ્ડર બંધ કરવા માટે ટૅપ કરો"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"નામ બદલવાનું સાચવવા માટે ટૅપ કરો"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ફોલ્ડર બંધ કર્યું"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ફોલ્ડરનું નામ બદલીને <xliff:g id="NAME">%1$s</xliff:g> કર્યું"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"વિજેટ્સ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"સેટિંગ્સ"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"વિહંગાવલોકન"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"આઇકનનો આકાર બદલો"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"બદલશો નહીં"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"આઇકનના આકારમાં કરેલ ફેરફારો લાગુ કરી રહ્યા છીએ"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"અજાણ્યો"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"દૂર કરો"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"શોધો"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"આ ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"આ આયકન માટેની ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી. તમે તેને દૂર કરી શકો છો અથવા ઍપ્લિકેશન માટે શોધ કરી અને તેને મેન્યુઅલી ઇન્સ્ટોલ કરી શકો છો."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ડાઉનલોડ કરી રહ્યાં છે, <xliff:g id="PROGRESS">%2$s</xliff:g> પૂર્ણ"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>, ઇન્સ્ટૉલ થવાની રાહ જોઈ રહ્યું છે"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> વિજેટ"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"હોમ સ્ક્રીન પર ઉમેરો"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"આઇટમ અહીં ખસેડો"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"હોમ સ્ક્રીનમાં આઇટમ ઉમેરી"</string>
+ <string name="item_removed" msgid="851119963877842327">"આઇટમ દૂર કરી"</string>
+ <string name="action_move" msgid="4339390619886385032">"આઇટમ ખસેડો"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> પંક્તિ <xliff:g id="NUMBER_1">%2$s</xliff:g> કૉલમ પર ખસેડો"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> સ્થિતિ પર ખસેડો"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"મનપસંદ સ્થિતિ <xliff:g id="NUMBER">%1$s</xliff:g> પર ખસેડો"</string>
+ <string name="item_moved" msgid="4606538322571412879">"આઇટમ ખસેડી"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ફોલ્ડરમાં ઉમેરો: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> સાથે ફોલ્ડરમાં ઉમેરો"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ફોલ્ડરમાં આઇટમ ઉમેરી"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"આની સાથે ફોલ્ડર બનાવો: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ફોલ્ડર બનાવ્યું"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"હોમ સ્ક્રીન પર ખસેડો"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"સ્ક્રીનને ડાબી બાજુ ખસેડો"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"સ્ક્રીનને જમણી બાજુ ખસેડો"</string>
+ <string name="screen_moved" msgid="266230079505650577">"સ્ક્રીન ખસેડી"</string>
+ <string name="action_resize" msgid="1802976324781771067">"આકાર બદલો"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"પહોળાઈ વધારો"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"ઊંચાઈ વધારો"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"પહોળાઈ ઘટાડો"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"ઊંચાઈ ઘટાડો"</string>
+ <string name="widget_resized" msgid="9130327887929620">"વિજેટનો આકાર બદલીને <xliff:g id="NUMBER_0">%1$s</xliff:g> પહોળાઈ <xliff:g id="NUMBER_1">%2$s</xliff:g> ઊંચાઈ કર્યો"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"શૉર્ટકટ્સ"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> માટે <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> શૉર્ટકટ"</string>
+</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
new file mode 100644
index 000000000..7c39a3f18
--- /dev/null
+++ b/res/values-hy/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Աշխատանքային"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Ծրագիրը տեղադրված չէ:"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Հավելվածը հասանելի չէ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Ներբեռնված ծրագիրն անջատված է Անվտանգ ռեժիմում"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Վիջեթներն անջատված են անվտանգ ռեժիմում"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Դյուրանցումն անհասանելի է"</string>
+ <string name="home_screen" msgid="806512411299847073">"Հիմնական էկրան"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Հատուկ գործողություններ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Հպեք և պահեք՝ վիջեթն ընտրելու համար:"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Հպեք և պահեք՝ ձեռքով տեղադրելու համար"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Ավելացնել ավտոմատ կերպով"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Ծանուցումներ"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Այլևս տեղ չկա այս հիմնական էկրանին:"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ընտրյալների ցուցակում այլևս ազատ տեղ չկա"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Հավելվածների ցանկ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Հիմնական"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Հեռացնել"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Հեռացնել"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Հավելվածի տվյալներ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"տեղադրել դյուրանցումներ"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ծրագրին թույլ է տալիս ավելացնել դյուրանցումներ՝ առանց օգտագործողի միջամտության:"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Ծրագրին թույլ է տալիս կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ստեղծել հիմնաէջի կարգավորումներ ու դյուրանցումներ"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Ծրագրին թույլ է տալիս փոփոխել հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածին չի թույլատրվում հեռախոսազանգեր կատարել"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Վիջեթի բեռնման խնդիր կա"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Կարգավորում"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Սա համակարգային ծրագիր է և չի կարող ապատեղադրվել:"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Անանուն պանակ"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն անջատված է"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Էջ %1$d՝ %2$d-ից"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Հիմնական էկրան %1$d` %2$d-ից"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Հիմնական էկրանի նոր էջ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Պանակը բաց է, <xliff:g id="WIDTH">%1$d</xliff:g>-ից <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Հպեք՝ պանակը փակելու համար"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Հպեք՝ նոր անվանումը պահելու համար"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Պանակը փակ է"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Պանակը վերանվանվեց <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Վիջեթներ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Կարգավորումներ"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Համատեսք"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Հեռացնել"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"Գտնել"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Այս ծրագիրը տեղադրված չէ:"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Այս պատկերակի ծրագիրը տեղադրված չէ: Դուք կարող եք հեռացնել այն կամ գտնել ծրագիրը և տեղադրել այն ձեռքով:"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>–ի ներբեռնում (<xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>-ի տեղադրման սպասում"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> վիջեթներ"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Ավելացնել Հիմնական էկրանին"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Տեղափոխել տարրն այստեղ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Տարրն ավելացվեց հիմնական էկրանին"</string>
+ <string name="item_removed" msgid="851119963877842327">"Տարրը հեռացվեց"</string>
+ <string name="action_move" msgid="4339390619886385032">"Տեղափոխել տարրը"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Տեղափոխել տող <xliff:g id="NUMBER_0">%1$s</xliff:g> սյունակ <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Տեղափոխել դիրք <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Տեղափոխել նախընտրած դիրք՝ <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Տարրը տեղափոխվեց"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Ավելացնել թղթապանակում՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Ավելացնել «<xliff:g id="NAME">%1$s</xliff:g>» պանակին"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Տարրն ավելացվեց թղթապանակում"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Ստեղծել թղթապանակ, օգտագործելով՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Պանակը ստեղծվեց"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Տեղափոխել Հիմնական էկրան"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Տեղափոխել էկրանը ձախ"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Տեղափոխել էկրանը աջ"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Էկրանը տեղափոխվեց"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Չափափոխել"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Ավելացնել լայնությունը"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Ավելացնել բարձրությունը"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Նվազեցնել լայնությունը"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Նվազեցնել բարձրությունը"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Վիջեթի լայնությունը փոխվել է <xliff:g id="NUMBER_0">%1$s</xliff:g>-ի, իսկ բարձրությունը՝ <xliff:g id="NUMBER_1">%2$s</xliff:g>-ի"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Դյուրանցումներ"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> դյուրանցումներ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածի համար"</string>
+</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
new file mode 100644
index 000000000..3694a10e4
--- /dev/null
+++ b/res/values-is/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Vinna"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Forritið er ekki uppsett."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Forritið er ekki í boði"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Sótt forrit er óvirkt í öryggisstillingu"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Græjur eru óvirkar í öruggri stillingu"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Flýtileið er ekki tiltæk"</string>
+ <string name="home_screen" msgid="806512411299847073">"Heimaskjár"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Sérsniðnar aðgerðir"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Haltu fingri á græju til að grípa hana."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Haltu inni til að staðsetja handvirkt"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Bæta sjálfkrafa við"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Leita að fleiri forritum"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Ekki meira pláss á þessum heimaskjá."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ekki meira pláss í bakka fyrir uppáhald"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Forritalisti"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Heim"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Fjarlægja"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Fjarlægja"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Forritsupplýsingar"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"setja upp flýtileiðir"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Leyfir forriti að bæta við flýtileiðum án íhlutunar notanda."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"lesa stillingar og flýtileiðir heimaskjás"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Leyfir forriti að lesa stillingar og flýtileiðir heimaskjás."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"skrifa stillingar og flýtileiðir heimaskjás"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> hefur ekki leyfi til að hringja símtöl"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Vandamál við að hlaða græju"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Uppsetning"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Þetta er kerfisforrit sem ekki er hægt að fjarlægja."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Ónefnd mappa"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"Óvirkt <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Síða %1$d af %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Heimaskjár %1$d af %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Ný síða á heimaskjá"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Mappa opnuð, <xliff:g id="WIDTH">%1$d</xliff:g> sinnum <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Ýttu til að loka möppunni"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ýttu til að vista breytt heiti"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Möppu lokað"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Heiti möppu breytt í <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Græjur"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Veggfóður"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Stillingar"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Yfirlit"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Þetta forrit er ekki uppsett"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Forritið fyrir þetta tákn er ekki uppsett. Þú getur fjarlægt það eða leitað að forritinu og sett það upp handvirkt."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> í niðurhali, <xliff:g id="PROGRESS">%2$s</xliff:g> lokið"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> bíður uppsetningar"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-græjur"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Bæta á heimaskjá"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Færa atriði hingað"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Atriði bætt á heimaskjáinn"</string>
+ <string name="item_removed" msgid="851119963877842327">"Atriði fjarlægt"</string>
+ <string name="action_move" msgid="4339390619886385032">"Færa atriði"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Færa í línu <xliff:g id="NUMBER_0">%1$s</xliff:g>, dálk <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Færa í stöðu <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Færa í stöðu <xliff:g id="NUMBER">%1$s</xliff:g> á festisvæði"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Atriði fært"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Setja í möppu: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Setja í möppu með <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Atriði sett í möppu"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Búa til möppu með: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Mappa búin til"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Færa á heimaskjá"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Færa skjá til vinstri"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Færa skjá til hægri"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Skjár færður"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Breyta stærð"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Auka breidd"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Auka hæð"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Minnka breidd"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Minnka hæð"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Stærð græju breytt í <xliff:g id="NUMBER_0">%1$s</xliff:g> á breidd og <xliff:g id="NUMBER_1">%2$s</xliff:g> á hæð"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Flýtileiðir"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> flýtileiðir fyrir <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
new file mode 100644
index 000000000..197944936
--- /dev/null
+++ b/res/values-ka/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"სამუშაო"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"აპი არ არის დაყენებული."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"აპი მიუწვდომელია"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"უსაფრთხო რეჟიმში ჩამოტვირთული აპი გაუქმებულია"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"უსაფრთხო რეჟიმში ვიჯეტი გამორთულია"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"მალსახმობი მიუწვდომელია"</string>
+ <string name="home_screen" msgid="806512411299847073">"მთავარი ეკრანი"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"მორგებული ქმედებები"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"შეეხეთ და დააყოვნეთ ვიჯეტის ასარჩევად."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ხანგრძლივად შეეხეთ ხელით განსათავსებლად"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ავტომატურად დამატება"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ამ მთავარ ეკრანზე ადგილი აღარ არის."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"რჩეულების თაროზე ადგილი არ არის"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"აპების სია"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"მთავარი"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ამოშლა"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"დეინსტალაცია"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"აპის შესახებ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"მალსახმობების დაყენება"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"აპისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვა"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვის უფლების მიცემა."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების ჩაწერა"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების შეცვლის უფლების მიცემა."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს სატელეფონო ზარების განხორციელების უფლება"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"პრობლემა ვიჯეტის ჩატვირთვისას"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"დაყენება"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ეს სისტემური აპია და მისი წაშლა შეუძლებელია."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"უსახელო საქაღალდე"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაითიშა"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"გვერდი %1$d %2$d-დან"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"მთავარი ეკრანი %1$d, %2$d-დან"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"მთავარი ეკრანის ახალი გვერდი"</string>
+ <string name="folder_opened" msgid="94695026776264709">"საქაღალდე გახსნილია, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"შეეხეთ საქაღალდის დასახურად"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"შეეხეთ გადარქმეული სახელის შესანახად"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"საქაღალდე დაიხურა"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"საქაღალდეს შეეცვალა სახელი „<xliff:g id="NAME">%1$s</xliff:g>“-ად"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ვიჯეტები"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"პარამეტრები"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"მიმოხილვა"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ამოშლა"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ძიება"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"ეს აპი დაყენებული არ არის"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ამ ხატულის აპი დაყენებული არ არის. შეგიძლიათ ამოშალოთ, ან მოიძიოთ აპი და ხელით მოახდინოთ მისი ინსტალაცია."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"მიმდინარეობს <xliff:g id="NAME">%1$s</xliff:g>-ის ჩამოტვირთვა, <xliff:g id="PROGRESS">%2$s</xliff:g> დასრულდა"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ელოდება ინსტალაციას"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-ის ვიჯეტები"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"მთავარ ეკრანზე დამატება"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"ერთეულის გადაადგილება აქ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ერთეული დაემატა მთავარ ეკრანს"</string>
+ <string name="item_removed" msgid="851119963877842327">"ერთეული წაიშალა"</string>
+ <string name="action_move" msgid="4339390619886385032">"ერთეულის გადაადგილება"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"გადატანა რიგში <xliff:g id="NUMBER_0">%1$s</xliff:g> სვეტში <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"გადატანა <xliff:g id="NUMBER">%1$s</xliff:g> პოზიციაზე"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"გადატანა რჩეულთა პოზიციაზე <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"ერთეული გადაადგილდა"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"საქაღალდეში დამატება: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"საქაღალდეში დამატება <xliff:g id="NAME">%1$s</xliff:g>-ით"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ერთეული დაემატა საქაღალდეს"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"საქაღალდის შექმნა ერთეულით: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"საქაღალდე შექმნილია"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"მთავარ ეკრანზე გადატანა"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"ეკრანის გადატანა მარცხნივ"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"ეკრანის გადატანა მარჯვნით"</string>
+ <string name="screen_moved" msgid="266230079505650577">"ეკრანი გადაადგილდა"</string>
+ <string name="action_resize" msgid="1802976324781771067">"ზომის შეცვლა"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"სიგანის გაზრდა"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"სიმაღლის გაზრდა"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"სიგანის შემცირება"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"სიმაღლის შემცირება"</string>
+ <string name="widget_resized" msgid="9130327887929620">"ვიჯეტის ზომები შეიცვალა: სიგანე <xliff:g id="NUMBER_0">%1$s</xliff:g> სიმაღლე <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"მალსახმობები"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>-ს აქვს <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> მალსახმობი"</string>
+</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
new file mode 100644
index 000000000..5df503a10
--- /dev/null
+++ b/res/values-kk/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Жұмыс"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Қолданба орнатылмаған."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Қолданба қол жетімді емес"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Жүктелген қолданба қауіпсіз режимде өшірілген"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Қауіпсіз режимде виджеттер өшіріледі"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Таңбаша қолжетімді емес"</string>
+ <string name="home_screen" msgid="806512411299847073">"Негізгі экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Арнаулы әрекеттер"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетті таңдау үшін түртіп, мықтап ұстаңыз."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Қолмен қою үшін басып тұрыңыз"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматты енгізу"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Бұл Негізгі экранда орын қалмады."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Қалаулылар науасында орын қалмады"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Қолданбалар тізімі"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Негізгі"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Жою"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Жою"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Қолданба ақпараты"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"төте пернелерді орнату"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Қолданбаға пайдаланушының қатысуынсыз төте пернелерді қосу мүмкіндігін береді."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"Негізгі экрандағы параметрлер мен төте пернелерді оқу"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді оқу мүмкіндігін береді."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"Негізгі экран параметрлері мен төте пернелерін жазу"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді өзгерту мүмкіндігін береді."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> арқылы телефон қоңырауларын соғуға рұқсат етілмеген"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Виджетті жүктеу барысында мәселе орын алды"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Орнату"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Бұл жүйе қолданбасы, сондықтан оны алу мүмкін емес."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Атауы жоқ қалта"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өшірілді"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%1$d бет, барлығы %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d негізгі экран, барлығы %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Жаңа негізгі экран беті"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Қалта ашылды, <xliff:g id="WIDTH">%1$d</xliff:g> және <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Қалтаны жабу үшін түртіңіз"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Қайта атауды сақтау үшін түртіңіз"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Қалта жабылды"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Қалта атауы <xliff:g id="NAME">%1$s</xliff:g> болып өзгертілді"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Параметрлер"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Шолу"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"Белгісіз"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Алып тастау"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"Іздеу"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Бұл қолданба орнатылмаған"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Осы белгіше үшін қолданба орнатылмаған. Оны жоюға болады немесе қолданбаны іздеп, қолмен орнатуға болады."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> жүктелуде, <xliff:g id="PROGRESS">%2$s</xliff:g> аяқталды"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> орнату күтілуде"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> виджеті"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Негізгі экранға қосу"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Элементті мұнда жылжыту"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Элемент негізгі экранға қосылды"</string>
+ <string name="item_removed" msgid="851119963877842327">"Элемент жойылды"</string>
+ <string name="action_move" msgid="4339390619886385032">"Элементті жылжыту"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g>-жол, <xliff:g id="NUMBER_1">%2$s</xliff:g>-бағанға жылжыту"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g>-орынға жылжыту"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"<xliff:g id="NUMBER">%1$s</xliff:g> нөмірлі таңдаулы орынға жылжыту"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Элемент жылжытылды"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Қалтаға қосу: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> бар қалтаға қосу"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Элемент қалтаға қосылды"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Мына бар қалтаны жасау: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Қалта жасалды"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Негізгі экранға жылжыту"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Экранды солға жылжыту"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Экранды оңға жылжыту"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Экран жылжытылды"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Өлшемін өзгерту"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Енін арттыру"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Биіктігін арттыру"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Енін азайту"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Биіктігін азайту"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Виджет өлшемінің ені <xliff:g id="NUMBER_0">%1$s</xliff:g>, биіктігі <xliff:g id="NUMBER_1">%2$s</xliff:g> болып өзгертілді"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Таңбашалар"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына арналған <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> таңбаша"</string>
+</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
new file mode 100644
index 000000000..a64b604cb
--- /dev/null
+++ b/res/values-km/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ការងារ"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"មិន​បាន​ដំឡើង​កម្មវិធី។"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"មិន​មាន​កម្មវិធី"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"បាន​បិទ​កម្មវិធី​ដែល​បាន​ទាញ​យក​ក្នុង​របៀប​សុវត្ថិភាព"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"បាន​បិទ​ធាតុ​ក្រាហ្វិក​ក្នុង​របៀប​សុវត្ថិភាព"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"ផ្លូវកាត់មិនអាចប្រើបានទេ"</string>
+ <string name="home_screen" msgid="806512411299847073">"អេក្រង់ដើម"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"សកម្មភាព​ផ្ទាល់ខ្លួន"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ប៉ះ &amp; សង្កត់ ដើម្បី​ជ្រើស​ធាតុ​ក្រាហ្វិក។"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ចុច​ឲ្យជាប់​ដើម្បី​បញ្ចូលវា​ដោយផ្ទាល់"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"ការ​ជូនដំណឹង"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"គ្មាន​បន្ទប់​នៅ​លើ​អេក្រង់​ដើម​នេះ​ទៀត​ទេ។"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"គ្មាន​បន្ទប់​​ក្នុង​ថាស​និយម​ប្រើ"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"បញ្ជីកម្មវិធី"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ដើម"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"យកចេញ"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"លុបការដំឡើង"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ព័ត៌មាន​កម្មវិធី"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"ដំឡើង​ផ្លូវកាត់"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​បន្ថែម​ផ្លូវកាត់​ ដោយ​មិន​ចាំបាច់​​អំពើ​ពី​អ្នក​ប្រើ។"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"អាន​ការ​កំណត់​ និង​ផ្លូវកាត់​​អេក្រង់​ដើម"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​អាន​ការ​កំណត់ និង​ផ្លូវកាត់​ក្នុង​អេក្រង់​ដើម។"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"សរសេរ​ការ​កំណត់ ​និង​ផ្លូវកាត់​​លើ​អេក្រង់​ដើម"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់ និង​ផ្លូវ​កាត់​ក្នុង​អេក្រង់​ដើម។"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនត្រូវបានអនុញ្ញាតឲ្យធ្វើការហៅទូរស័ព្ទទេ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"បញ្ហា​ក្នុង​ការ​ផ្ទុក​ធាតុ​​ក្រាហ្វិក"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"រៀបចំ"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"នេះ​​​ជា​កម្មវិធី​ប្រព័ន្ធ មិន​អាច​លុប​បាន​ទេ។"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ថត​គ្មាន​ឈ្មោះ"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"បានបិទដំណើរការ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"ទំព័រ %1$d នៃ %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"ទំព័រអេក្រង់ដើមថ្មី"</string>
+ <string name="folder_opened" msgid="94695026776264709">"បាន​បើក​ថត <xliff:g id="WIDTH">%1$d</xliff:g> ដោយ <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ប៉ះ ដើម្បីបិទថត"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"ប៉ះដើម្បីរក្សាទុកឈ្មោះដែលបានប្តូរ"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"បាន​បិទ​ថត"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"បាន​ប្ដូរ​ឈ្មោះ​ថត​ជា <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ធាតុ​ក្រាហ្វិក"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំង​រូបភាព"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ការកំណត់"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"សង្ខេប"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"មិន​ស្គាល់"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"លុបចេញ"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ស្វែងរក"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"មិន​បាន​ដំឡើង​កម្មវិធី​នេះ"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"មិន​បាន​ដំឡើង​កម្មវិធី​សម្រាប់​រូបតំណាង​នេះ។ អ្នក​អាច​លុប​វា ឬ​ស្វែងរក​កម្មវិធី និង​ដំឡើង​វា​ដោយ​ដៃ។"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"កំពុងដោនឡូត <xliff:g id="NAME">%1$s</xliff:g> បានបញ្ចប់ <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> កំពុងរង់ចាំការដំឡើង"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"ធាតុ​ក្រាហ្វិក <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"បន្ថែមទៅអេក្រង់ដើម"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"ផ្លាស់ធាតុមកទីនេះ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ធាតុដែលត្រូវបានបន្ថែមទៅអេក្រង់ដើម"</string>
+ <string name="item_removed" msgid="851119963877842327">"ធាតុដែលបានដកចេញ"</string>
+ <string name="action_move" msgid="4339390619886385032">"ផ្លាស់ទីធាតុ"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"ផ្លាស់ទីទៅជួរដេកទី <xliff:g id="NUMBER_0">%1$s</xliff:g> ជួរឈរទី <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"ផ្លាស់ទីទៅទីតាំង <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ផ្លាស់ទីទៅការចូលចិត្តទីតាំងទី <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"បានផ្លាស់ទីធាតុ"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"បន្ថែមទៅថតឯកសារ៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"បន្ថែមទៅថតឯកសារដែលមានឈ្មោះ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"បានបន្ថែមធាតុទៅថតឯកសារ"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"បង្កើតថតឯកសារជាមួយ៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"បានបង្កើតថតឯកសារ"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ផ្លាស់ទៅអេក្រង់ដើម"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"រំកិលអេក្រង់ទៅខាងឆ្វេង"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"រំកិលអេក្រង់ទៅខាងស្តាំ"</string>
+ <string name="screen_moved" msgid="266230079505650577">"អេក្រង់ដែលបានផ្លាស់ទី"</string>
+ <string name="action_resize" msgid="1802976324781771067">"ប្ដូរទំហំ"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"បង្កើនទទឹង"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"បង្កើនកម្ពស់"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"បន្ថយទទឹង"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"បន្ថយកម្ពស់"</string>
+ <string name="widget_resized" msgid="9130327887929620">"ធាតុក្រាហ្វិកដែលបានប្តូរទំហំទៅទទឹងប្រវែង <xliff:g id="NUMBER_0">%1$s</xliff:g> កម្ពស់ប្រវែង <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"ផ្លូវកាត់"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ផ្លូវកាត់សម្រាប់ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-kn/config.xml b/res/values-kn/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-kn/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
new file mode 100644
index 000000000..b22af0de8
--- /dev/null
+++ b/res/values-kn/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ಕೆಲಸ"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ಡೌನ್‌ಲೋಡ್ ಮಾಡಲಾದ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ವಿಜೆಟ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"ಶಾರ್ಟ್‌ಕಟ್ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="home_screen" msgid="806512411299847073">"ಮುಖಪುಟದ ಪರದೆ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳು"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ಹಸ್ತಚಾಲಿತವಾಗಿ ಸೇರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೇರಿಸಿ"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"ಮೆಚ್ಚಿನವುಗಳ ಟ್ರೇನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಪಟ್ಟಿ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ಮುಖಪುಟ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ತೆಗೆದುಹಾಕಿ"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"ಅಸ್ಥಾಪಿಸು"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"ಬಳಕೆದಾರರ ಹಸ್ತಕ್ಷೇಪವಿಲ್ಲದೆ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಿ"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬರೆಯಿರಿ"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು <xliff:g id="APP_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ವಿಜೆಟ್ ಲೋಡ್‌ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ಸೆಟಪ್"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d ರಲ್ಲಿ %1$d ಪುಟ"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d ರಲ್ಲಿ %1$d ಮುಖಪುಟದ ಪರದೆ"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"ಹೊಸ ಮುಖಪುಟ ಪರದೆ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ಫೋಲ್ಡರ್ ತೆರೆಯಲಾಗಿದೆ, <xliff:g id="WIDTH">%1$d</xliff:g> ಬೈ <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ಫೋಲ್ಡರ್‌ ಮುಚ್ಚಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"ಮರುಹೆಸರನ್ನು ಉಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ಫೋಲ್ಡರ್ ಮುಚ್ಚಿದೆ"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ಫೋಲ್ಡರ್‌ ಅನ್ನು <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಮರುಹೆಸರಿಸಲಾಗಿದೆ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ವಿಜೆಟ್‌ಗಳು"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"ಅವಲೋಕನ"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"ಬದಲಿಸಬೇಡಿ"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"ಐಕಾನ್ ಆಕಾರ ಬದಲಾವಣೆಯನ್ನು ಅನ್ವಯಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"ಅಪರಿಚಿತ"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ತೆಗೆದುಹಾಕಿ"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ಹುಡುಕಿ"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ಈ ಐಕಾನ್ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ. ನೀವು ಅದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಹುಡುಕಬಹುದು ಮತ್ತು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅದನ್ನು ಸ್ಥಾಪಿಸಬಹುದು."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ಡೌನ್‌ಲೋಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ, <xliff:g id="PROGRESS">%2$s</xliff:g> ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಕಾಯಲಾಗುತ್ತಿದೆ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ವಿಜೆಟ್‌ಗಳು"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸು"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"</string>
+ <string name="item_removed" msgid="851119963877842327">"ಐಟಂ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
+ <string name="action_move" msgid="4339390619886385032">"ಐಟಂ ಸರಿಸಿ"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ಸಾಲು <xliff:g id="NUMBER_1">%2$s</xliff:g> ಕಾಲಮ್‌ಗೆ ಸರಿಸಿ"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> ಸ್ಥಾನಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ಮೆಚ್ಚಿನ <xliff:g id="NUMBER">%1$s</xliff:g> ಸ್ಥಾನಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="item_moved" msgid="4606538322571412879">"ಐಟಂ ಸರಿಸಲಾಗಿದೆ"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ಫೋಲ್ಡರ್‌ಗೆ ಸೇರಿಸಿ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ಮೂಲಕ ಫೋಲ್ಡರ್‌ಗೆ ಸೇರಿಸಿ"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ಐಟಂ ಅನ್ನು ಫೋಲ್ಡರ್‌ಗೆ ಸೇರಿಸಲಾಗಿದೆ"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಫೋಲ್ಡರ್ ರಚಿಸಿ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ಫೋಲ್ಡರ್ ರಚಿಸಲಾಗಿದೆ"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ಮುಖಪುಟಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"ಪರದೆಯನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"ಪರದೆಯನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="screen_moved" msgid="266230079505650577">"ಪರದೆ ಸರಿಸಲಾಗಿದೆ"</string>
+ <string name="action_resize" msgid="1802976324781771067">"ಮರುಗಾತ್ರ"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"ಅಗಲವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"ಎತ್ತರವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"ಅಗಲವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"ಎತ್ತರವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
+ <string name="widget_resized" msgid="9130327887929620">"ವಿಜೆಟ್ ಅನ್ನು <xliff:g id="NUMBER_0">%1$s</xliff:g> ಅಗಲ <xliff:g id="NUMBER_1">%2$s</xliff:g> ಎತ್ತರಕ್ಕೆ ಮರುಗಾತ್ರಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
new file mode 100644
index 000000000..21622924d
--- /dev/null
+++ b/res/values-ky/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Жумуш"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Колдонмо орнотулган эмес."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Колдонмо жеткиликтүү эмес"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Жүктөп алынган колдонмо Коопсуз режиминде иштен чыгарылды"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Виджеттер Коопсуз режимде өчүрүлгөн"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Кыска жол жок"</string>
+ <string name="home_screen" msgid="806512411299847073">"Башкы экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Ыңгайлаштырылган аракеттер"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетти тандаш үчүн, басып туруңуз"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Кол менен жайгаштыруу үчүн басып туруп, таштаңыз"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматтык түрдө кошуу"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Эскертмелер"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Бул Үй экранында бош орун жок."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Тандамалдар тайпасында орун калган жок"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Колдонмолор тизмеси"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Үйгө"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Алып салуу"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Чыгарып салуу"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Колдонмо тууралуу"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"тез чакырмаларды орнотуу"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"Үйдүн тууралоолорун жана тез чакырмаларын окуу"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын окууга уруксат берет."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"Үйдүн тууралоолорун жана тез чакырмаларын жазуу"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын өзгөртүүгө уруксат берет."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> телефон чалууларды аткарууга уруксаты жок"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Виджетти жүктөөдө маселе бар"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Орнотуу"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Бул системдик колдонмо жана аны чечкенге болбойт."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Аты жок фолдер"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өчүрүлгөн"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d ичинен %1$d барак"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Үй экраны %2$d ичинен %1$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Жаңы башкы экран барагы"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Фолдер ачылды, туурасы <xliff:g id="WIDTH">%1$d</xliff:g>, бийиктиги <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Куржунду жабуу үчүн таптаңыз"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Өзгөртүлгөн аталышын сактоо үчүн таптаңыз"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Фолдер жабык"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Фолдердин аты <xliff:g id="NAME">%1$s</xliff:g> деп өзгөртүлдү"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Тууралоолор"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Көз жүгүртүү"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"Белгисиз"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Алып салуу"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"Издөө"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Бул колдонмо орнотулган эмес"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Бул сүрөтчөнүн колдонмосу орнотулган эмес. Аны алып салсаңыз же колдонмону издеп, кол менен орнотсоңуз болот."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> жүктөлүп алынууда, <xliff:g id="PROGRESS">%2$s</xliff:g> аяктады"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> орнотулушу күтүлүүдө"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> виджеттери"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Башкы экранга кошуу"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Бул нерсени бул жерге жылдыруу"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Башкы экранга кошулду"</string>
+ <string name="item_removed" msgid="851119963877842327">"Жоюлду"</string>
+ <string name="action_move" msgid="4339390619886385032">"Муну жылдыруу"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> катарга <xliff:g id="NUMBER_1">%2$s</xliff:g> тилкеге жылдыруу"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> орунга жылдыруу"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Сүйүктүүлөргө <xliff:g id="NUMBER">%1$s</xliff:g> жылдыруу"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Нерсе жылдырылды"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Куржунга кошуу: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> куржунуна кошуу"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Нерсе куржунга кошулду"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Төмөнкү менен куржун түзүү: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Куржун түзүлдү"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Башкы экранга жылдыруу"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Экранды солго жылдыруу"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Экранды оңго жылдыруу"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Экран жылдырылды"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Өлчөмүн өзгөртүү"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Кеңейтүү"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Бийиктетүү"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Ичкертүү"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Жапыздатуу"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Виджеттин кеңдиги <xliff:g id="NUMBER_0">%1$s</xliff:g> бийиктиги <xliff:g id="NUMBER_1">%2$s</xliff:g> болду"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Кыска жолдор"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосуна <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кыска жол бар"</string>
+</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
new file mode 100644
index 000000000..334305afe
--- /dev/null
+++ b/res/values-lo/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ວຽກ"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ແອັບຯ​ໃຊ້​ບໍ່​ໄດ້"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ແອັບຯ​ທີ່​ດາວ​ໂຫລດ​ແລ້ວ​ຖືກ​ປິດ​ການ​ນຳ​ໃຊ້​ໃນ Safe mode"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"​ວິດ​ເຈັດ​ຖືກ​ປິດ​ໃນ Safe mode"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"ບໍ່ສາມາດໃຊ້ທາງລັດໄດ້"</string>
+ <string name="home_screen" msgid="806512411299847073">"ໜ້າຈໍຫຼັກ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ຄຳສັ່ງແບບກຳນົດເອງ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ສຳພັດຄ້າງໄວ້ ເພື່ອຈັບວິດເຈັດ."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ແຕະຄ້າງໄວ້ເພື່ອວາງດ້ວຍຕົນເອງ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ເພີ່ມໂດຍອັດຕະໂນມັດ"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"ບໍ່ມີບ່ອນຫວ່າງໃນຖາດສຳລັບເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"ລາຍຊື່ແອັບ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ໜ້າຫຼັກ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ເອົາ​ອອກ"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"ຖອນ​ການ​ຕິດ​ຕັ້ງ"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ຂໍ້ມູນແອັບ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"ຕິດຕັ້ງທາງລັດ"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມທາງລັດໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ອ່ານການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວອ່ານການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ຂຽນການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ປ່ຽນການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່​ໄດ້​ຮັບ​ອະ​ນຸ​ຍາດ​ໃຫ້​ໂທ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ມີບັນຫາໃນການໂຫລດວິດເຈັດ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ຕິດຕັ້ງ"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ນີ້ແມ່ນແອັບຯຂອງລະບົບ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງອອກໄດ້."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"ປິດການນຳໃຊ້ <xliff:g id="APP_NAME">%1$s</xliff:g> ແລ້ວ"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"ໜ້າ %1$d ຈາກ %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"ໜ້າຈໍຫຼັກ %1$d ໃນ %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"ໜ້າ​ຂອງ​ໜ້າ​ຈໍ​ຫຼັກ​ໃໝ່"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ເປີດໂຟນເດີແລ້ວ, <xliff:g id="WIDTH">%1$d</xliff:g> ຄູນ <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ແຕະເພື່ອປິດໂຟນເດີ"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"ແຕະເພື່ອບັນທຶກການປ່ຽນຊື່"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ປິດໂຟນເດີແລ້ວ"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ປ່ຽນຊື່ໂຟນເດີເປັນ <xliff:g id="NAME">%1$s</xliff:g> ແລ້ວ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ວິດເຈັດ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ການຕັ້ງຄ່າ"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"ພາບຮວມ"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"​ບໍ່​ຮູ້​ຈັກ"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ​"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"ແອັບຯ​ນີ້​ຍັງ​ບໍ່​ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"​ແອັບຯ​ສຳ​ລັບ​ໄອ​ຄອນ​ນີ້​ຍັງ​ບໍ່ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ. ທ່ານ​ສາ​ມາດ​ລຶບ​ມັນ​ອອກ ຫຼື​ຊອກ​ຫາ​ແອັບຯ ແລ້ວ​ຕິດ​ຕັ້ງ​ມັນ​ໄດ້​ດ້ວຍ​ຕົນ​ເອງ."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ກຳ​ລັງ​ດາວ​ໂຫຼດ, <xliff:g id="PROGRESS">%2$s</xliff:g> ສຳ​ເລັດ"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ກຳ​ລັງ​ລໍ​ຖ້າ​ຕິດ​ຕັ້ງ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"ວິດເຈັດ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Move item here"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ເພີ່ມ​ລາຍ​ການ​ໃສ່​ໜ້າ​ຈໍ​ຫຼັກ​ແລ້ວ"</string>
+ <string name="item_removed" msgid="851119963877842327">"ເອົາ​ລາຍ​ການ​ອອກ​ໄປ​ແລ້ວ"</string>
+ <string name="action_move" msgid="4339390619886385032">"ຍ້າຍ​ລາຍ​ການ"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"ຍ້າຍ​ໄປ​ໃສ່​ແຖວ <xliff:g id="NUMBER_0">%1$s</xliff:g> ຖັນ <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"ຍ້າຍ​ໄປ​ໃສ່​ຕຳ​ແໜ່ງ <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ຍ້າຍ​ໄປ​ໃສ່​ຕຳ​ແໜ່ງ​ທີ່​ມັກ <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"ຍ້າຍ​ລາຍ​ການ​ແລ້ວ"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ເພີ່ມ​ໃສ່​ໂຟ​ລ​ເດີ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"ເພີ່ມ​ໃສ່​ໂຟ​ລ​ເດີ​ດ້ວຍ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ເພີ່ມ​ລາຍ​ການ​ໃສ່​ໂຟ​ລ​ເດີ​ແລ້ວ"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ສ້າງ​ໂຟ​ລ​ເດີ​ກັບ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ສ້າງ​ໂຟ​ລ​ເດີ​ແລ້ວ"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ຍ້າຍ​ໄປ​ໃສ່​ໜ້າ​ຈໍ​ຫຼັກ"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"ຍ້າຍ​ໜ້າ​ຈໍ​ໄປ​ທາງ​ຊ້າຍ"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"ຍ້າຍ​ໜ້າ​ຈໍ​ໄປ​ທາງ​ຂວາ"</string>
+ <string name="screen_moved" msgid="266230079505650577">"ຍ້າຍ​ໜ້າ​ຈໍ​ແລ້ວ"</string>
+ <string name="action_resize" msgid="1802976324781771067">"ປັບຂະໜາດ"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"ເພີ່ມ​ລວງ​ກ້​ວາງ​ຂຶ້ນ"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"ເພີ່ມ​ລວງ​ສູງ​ຂຶ້ນ"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"ຫຼຸດ​ລວງ​ກ້​ວາງ​ລົງ"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"ຫຼຸດ​ລວງ​ສູງ​ລົງ"</string>
+ <string name="widget_resized" msgid="9130327887929620">"ປ່ຽນ​ຂະ​ໜາດ​ວິດ​ເຈັດ​ເປັນ​ລວງ​ກ້​ວາງ <xliff:g id="NUMBER_0">%1$s</xliff:g> ລວງ​ສູງ <xliff:g id="NUMBER_1">%2$s</xliff:g> ແລ້ວ"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"ທາງລັດ"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ທາງລັດສຳລັບ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
new file mode 100644
index 000000000..267e75b98
--- /dev/null
+++ b/res/values-mk/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Стартер3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Апликацијата не е инсталирана."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Апликацијата не е достапна"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Преземената апликација е оневозможена во безбеден режим"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Додатоците се оневозможени во безбеден режим"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Кратенката не е достапна"</string>
+ <string name="home_screen" msgid="806512411299847073">"Почетен екран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Приспособени дејства"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Допри и задржи за да се избере виџетот."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Допрете и задржете за рачно поставување"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Додај автоматски"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Известувања"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Нема повеќе простор на овој екран на почетната страница."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Нема повеќе простор на лентата „Омилени“"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Список со апликации"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Почетна страница"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Отстрани"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Деинсталирај"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Инф. за апликација"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталирај кратенки"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Овозможува апликацијата да додава кратенки без интервенција на корисникот."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"чита поставки и кратенки на почетна страница"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"пишува поставки и кратенки на почетна страница"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> нема дозвола за телефонски повици"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Проблем при вчитувањето на виџетот"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Поставување"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ова е системска апликација и не може да се деинсталира."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Неименувана папка"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> е оневозможена"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Страница %1$d од %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Екран на почетна страница %1$d од %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Нова страница на почетен екран"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Отворена е папка, <xliff:g id="WIDTH">%1$d</xliff:g> на <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Допрете за да ја затворите папката"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Допрете за да го зачувате преименувањето"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Папката е затворена"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Папката е преименувана во <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Додатоци"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Позадини"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Поставки"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Краток преглед"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Отстрани"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"Барај"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Апликацијата не е инсталирана"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Апликацијата за оваа икона не е инсталирана. Може да ја отстраните или да се обидете да ја најдете апликацијата и да ја инсталирате рачно."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"Се презема <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> завршено"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чека да се инсталира"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Виџети за <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Додај на Почетен екран"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Премести ја ставката овде"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Ставката е додадена на почетниот екран"</string>
+ <string name="item_removed" msgid="851119963877842327">"Ставката е отстранета"</string>
+ <string name="action_move" msgid="4339390619886385032">"Премести ја ставката"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Премести во ред <xliff:g id="NUMBER_0">%1$s</xliff:g> колона <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Премести на место <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Премести на место <xliff:g id="NUMBER">%1$s</xliff:g> во омилени"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Ставката е преместена"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Додај во папката: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Додај во папка со <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Ставката е додадена во папката"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Создај папка со: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Папката е создадена"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Премести на Почетен екран"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Движи го екранот налево"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Движи го екранот надесно"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Екранот е преместен"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Промени големина"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Зголеми ширина"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Зголеми висина"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Намали ширина"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Намали висина"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Големината на виџетот е променета на ширина <xliff:g id="NUMBER_0">%1$s</xliff:g> висина <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Кратенки"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кратенки за <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-ml/config.xml b/res/values-ml/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-ml/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
new file mode 100644
index 000000000..a92fc0356
--- /dev/null
+++ b/res/values-ml/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"ലോഞ്ചർ3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ഔദ്യോഗികം"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"അപ്ലിക്കേഷൻ ഇൻസ്‌റ്റാളുചെ‌യ്‌തിട്ടില്ല."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"അപ്ലിക്കേഷൻ ലഭ്യമല്ല"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ഡൗൺലോഡുചെയ്‌ത അപ്ലിക്കേഷൻ സുരക്ഷാ മോഡിൽ പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"സുരക്ഷിത മോഡിൽ വിജറ്റുകൾ പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"കുറുക്കുവഴി ലഭ്യമല്ല"</string>
+ <string name="home_screen" msgid="806512411299847073">"ഹോം സ്‌ക്രീൻ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ഒരു വിജറ്റ് ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"സ്വമേധയാ സ്ഥാപിക്കുന്നതിന് സ്‌പർശിച്ചുപിടിക്കുക"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"സ്വയമേവ ചേർക്കുക"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"അറിയിപ്പുകൾ"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ഈ ഹോം സ്‌ക്രീനിൽ ഒഴിവൊന്നുമില്ല."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"പ്രിയപ്പെട്ടവയുടെ ട്രേയിൽ ഒഴിവൊന്നുമില്ല"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"അപ്ലിക്കേഷനുകളുടെ ലിസ്‌റ്റ്"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ഹോം"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"നീക്കംചെയ്യുക"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ആപ്പ് വിവരം"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"ഉപയോക്തൃ ഇടപെടൽ ഇല്ലാതെ കുറുക്കുവഴികൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യുക"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റൈറ്റുചെയ്യുക"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"ഫോൺ കോൾ ചെയ്യാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനെ അനുവദിച്ചിട്ടില്ല"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"വിജറ്റ് ലോഡുചെയ്യുന്നതിൽ പ്രശ്നമുണ്ട്"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"സജ്ജീകരിക്കുക"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ഇതൊരു സിസ്‌റ്റം അപ്ലിക്കേഷനായതിനാൽ അൺഇൻസ്‌റ്റാളുചെയ്യാനാവില്ല."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"പേരുനൽകാത്ത ഫോൾഡർ"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"പേജ് %1$d / %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"ഹോം സ്‌ക്രീൻ %1$d / %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"പുതിയ ഹോം സ്ക്രീൻ പേജ്"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ഫോൾഡർ തുറന്നു, <xliff:g id="WIDTH">%1$d</xliff:g> / <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ഫോൾഡർ അടയ്ക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"പേരുമാറ്റം സംരക്ഷിക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ഫോൾഡർ അടച്ചു"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ഫോൾഡറിന്റെ പേര് <xliff:g id="NAME">%1$s</xliff:g> എന്നായി മാറ്റി"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"വിജറ്റുകൾ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ക്രമീകരണം"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"കാഴ്ച"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"ഐക്കണിന്റെ ആകാരം മാറ്റുക"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"മാറ്റരുത്"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"ഐക്കൺ ആകാര മാറ്റങ്ങൾ പ്രയോഗിക്കുന്നു"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"അജ്ഞാതം"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"നീക്കംചെയ്യുക"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"തിരയുക"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വമേധയാ ഇൻസ്റ്റാളുചെയ്യുക."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ഡൗൺലോഡ് ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"ഇൻസ്റ്റാൾ ചെയ്യാൻ <xliff:g id="NAME">%1$s</xliff:g> കാക്കുന്നു"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> വിജറ്റുകൾ"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"ഹോം സ്ക്രീനിൽ ചേർക്കുക"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"ഇനം ഇവിടേക്ക് നീക്കുക"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ഹോം സ്‌ക്രീനിൽ ഇനം ചേർത്തു"</string>
+ <string name="item_removed" msgid="851119963877842327">"ഇനം നീക്കംചെയ്‌തു"</string>
+ <string name="action_move" msgid="4339390619886385032">"ഇനം നീക്കുക"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"വരി <xliff:g id="NUMBER_0">%1$s</xliff:g> നിര <xliff:g id="NUMBER_1">%2$s</xliff:g>-ലേക്ക് നീക്കുക"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g>-ലേക്ക് നീക്കുക"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ഇഷ്‌ടമുള്ള <xliff:g id="NUMBER">%1$s</xliff:g> സ്ഥാനത്തേക്ക് നീക്കുക"</string>
+ <string name="item_moved" msgid="4606538322571412879">"ഇനം നീക്കി"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ഫോൾഡറിൽ ചേർക്കുക: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ഉള്ള ഫോൾഡറിൽ ചേർക്കുക"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ഫോൾഡറിൽ ഇനം ചേർത്തു"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ഇതുപയോഗിച്ച് ഫോൾഡർ സൃഷ്‌ടിക്കുക: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ഫോൾഡർ സൃഷ്‌ടിച്ചു"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ഹോം സ്‌ക്രീനിലേക്ക് നീക്കുക"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"സ്‌ക്രീൻ ഇടത്തേക്ക് നീക്കുക"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"സ്‌ക്രീൻ വലത്തേക്ക് നീക്കുക"</string>
+ <string name="screen_moved" msgid="266230079505650577">"സ്‌ക്രീൻ നീക്കി"</string>
+ <string name="action_resize" msgid="1802976324781771067">"വലുപ്പംമാറ്റുക"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"വീതി കൂട്ടുക"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"ഉയരം കൂട്ടുക"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"വീതി കുറയ്‌ക്കുക"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"ഉയരം കുറയ്‌ക്കുക"</string>
+ <string name="widget_resized" msgid="9130327887929620">"വീതി <xliff:g id="NUMBER_0">%1$s</xliff:g> ഉയരം <xliff:g id="NUMBER_1">%2$s</xliff:g>-ലേക്ക് വിഡ്‌ജെറ്റിന്റെ വലുപ്പം മാറ്റി"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"കുറുക്കുവഴികൾ"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനുള്ള <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> കുറുക്കുവഴികൾ"</string>
+</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
new file mode 100644
index 000000000..5b74fd204
--- /dev/null
+++ b/res/values-mn/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Ажил"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Апп суугаагүй байна."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Апп-г ашиглах боломжгүй"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Татаж авсан апп-г Аюулгүй горим дотроос идэвхгүйжүүлсэн"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Safe горимд виджетүүдийг идэвхгүйжүүлсэн"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Товчлол алга"</string>
+ <string name="home_screen" msgid="806512411299847073">"Үндсэн нүүр"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Захиалгат үйлдэл"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетийг авах бол хүрээд барина уу."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Гараар байршуулахын тулд дараад хүлээнэ үү"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматаар нэмэх"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Мэдэгдэл"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Энэ Нүүр дэлгэц зайгүй."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"\"Дуртай\" трей дээр өөр зай байхгүй байна"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Апп-н жагсаалт"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Нүүр"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Арилгах"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Устгах"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Апп-н мэдээлэл"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"товчлол суулгах"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Апп нь хэрэглэгчийн оролцоогүйгээр товчлолыг нэмэж чадна"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"Нүүрний тохиргоо болон товчлолыг унших"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Апп нь Нүүрэндэх товчлол болон тохиргоог уншиж чадна."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"Нүүрний тохиргоо болон товчлолыг бичих"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Апп нь Нүүрэндэх товчлол болон тохиргоог өөрчилж чадна."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> утасны дуудлага хийх боломжгүй"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Виджет ачаалахад асуудал гарав"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Тохируулга"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Энэ апп нь системийн апп ба устгах боломжгүй."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Нэргүй фолдер"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г идэвхгүй болгосон"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d-н %1$d хуудас"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d-н Нүүр дэлгэц %1$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Шинэ үндсэн нүүр хуудас"</string>
+ <string name="folder_opened" msgid="94695026776264709">"<xliff:g id="WIDTH">%1$d</xliff:g> <xliff:g id="HEIGHT">%2$d</xliff:g> фолдер нээгдэв"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Фолдерийг хаахын тулд дарна уу"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Шинэ нэрийг хадгалахын тулд дарна уу."</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Фолдер хаагдав"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Фолдерын нэр <xliff:g id="NAME">%1$s</xliff:g> болов"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджет"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Ханын зураг"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Тохиргоо"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Тойм"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Устгах"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"Хайх"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Энэ апп-г суулгаагүй байна"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Энэ дүрсний апп-г суулгаагүй байна. Та үүнийг устгах буюу апп-г хайж суулгах боломжтой."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>-г татаж байна, <xliff:g id="PROGRESS">%2$s</xliff:g> татсан"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> нь суулгахыг хүлээж байна"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> жижиг хэрэгсэл"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Нүүр дэлгэц нэмэх"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Энд байршуулах"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Нүүр дэлгэцэнд нэмсэн зүйл"</string>
+ <string name="item_removed" msgid="851119963877842327">"Арилгасан зүйл"</string>
+ <string name="action_move" msgid="4339390619886385032">"Зөөх"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> мөр <xliff:g id="NUMBER_1">%2$s</xliff:g> баганад зөөх"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Байршил <xliff:g id="NUMBER">%1$s</xliff:g>-д зөөх"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Дуртай байршил болох <xliff:g id="NUMBER">%1$s</xliff:g>-д зөөх"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Зөөвөрлөсөн зүйл"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Хавтас: <xliff:g id="NAME">%1$s</xliff:g> руу нэм"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g>-тай хавтас нэмэх"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Хавтсанд нэмэгдсэн зүйл"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Хавтсыг: <xliff:g id="NAME">%1$s</xliff:g> нэрээр үүсгэ"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Үүсгэсэн хавтас"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Нүүр дэлгэц рүү зөөх"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Дэлгэцийг зүүн тийш зөөх"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Дэлгэцийг баруун тийш зөөх"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Дэлгэцийг зөөсөн"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Хэмжээг өөрчлөх"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Өргөсгөх"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Өндөрсгөх"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Нарийсгах"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Намсгах"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Виджэтийн өргөн <xliff:g id="NUMBER_0">%1$s</xliff:g>, өндөр <xliff:g id="NUMBER_1">%2$s</xliff:g> болсон"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Товчлол"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> товчлол"</string>
+</resources>
diff --git a/res/values-mr/config.xml b/res/values-mr/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-mr/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
new file mode 100644
index 000000000..1a10e4b57
--- /dev/null
+++ b/res/values-mr/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"अॅप स्थापित केलेला नाही."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"अॅप उपलब्ध नाही"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड केलेला अ‍ॅप सुरक्षित मोड मध्‍ये अक्षम केला"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोडमध्ये अक्षम झाले"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"शॉर्टकट उपलब्ध नाही"</string>
+ <string name="home_screen" msgid="806512411299847073">"मुख्यपृष्ठ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"सानुकूल क्रिया"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"स्वयंचलितपणे जोडा"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अॅप्स शोधा"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"या मुख्य स्क्रीनवर आणखी जागा नाही."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"आवडीच्या ट्रे मध्ये आणखी जागा नाही"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"अॅप्स सूची"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"मुख्‍यपृष्‍ठ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"काढा"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"विस्थापित करा"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"अॅप माहिती"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट स्‍थापित करा"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अॅप ला अनुमती देते."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट वाचा"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट लिहा"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ला फोन कॉल करण्याची अनुमती नाही"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करण्यात समस्या"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"हा सिस्टम अॅप आहे आणि विस्थापित केला जाऊ शकत नाही."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"अनामित फोल्डर"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम केला आहे"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d पैकी %1$d पृष्ठ"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d पैकी %1$d मुख्य स्क्रीन"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"नवीन मुख्य स्क्रीन पृष्ठ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"फोल्डर उघडले, <xliff:g id="WIDTH">%1$d</xliff:g> बाय <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"फोल्डर बंद करण्यासाठी टॅप करा"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"पुनर्नामित करणे जतन करण्यासाठी टॅप करा"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"फोल्डर बंद"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"फोल्डरचे नाव बदलून <xliff:g id="NAME">%1$s</xliff:g> असे ठेवले"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"सेटिंग्ज"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"विहंगावलोकन"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"चिन्हाचा आकार बदला"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"बदलू नका"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"चिन्हाचा आकार बदल लागू करत आहे"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"काढा"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"शोधा"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"हा अॅप स्थापित केलेला नाही"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"या चिन्हासाठी अॅप स्थापित केलेला नाही. आपण ते काढू शकता किंवा अॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे स्थापित करू शकता."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड होत आहे , <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> स्थापित करण्याची प्रतिक्षा करीत आहे"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेट"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"मुख्य स्क्रीनवर जोडा"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"आयटम येथे हलवा"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"आयटम मुख्य स्क्रीनवर जोडला"</string>
+ <string name="item_removed" msgid="851119963877842327">"आयटम काढला"</string>
+ <string name="action_move" msgid="4339390619886385032">"आयटम हलवा"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"पंक्ति <xliff:g id="NUMBER_0">%1$s</xliff:g> स्तंभ <xliff:g id="NUMBER_1">%2$s</xliff:g> मध्ये हलवा"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> स्थानावर हलवा"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"आवडत्या <xliff:g id="NUMBER">%1$s</xliff:g> स्थानावर हलवा"</string>
+ <string name="item_moved" msgid="4606538322571412879">"आयटम हलविला"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"फोल्‍डरवर जोडा: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> सह फोल्डरमध्ये जोडा"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"फोल्‍डरमध्‍ये आयटम जोडले"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"यासह फोल्‍डर तयार करा: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"फोल्‍डर तयार केले"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"मुख्य स्क्रीनवर हलवा"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"स्क्रीन डावीकडे हलवा"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"स्क्रीन उजवीकडे हलवा"</string>
+ <string name="screen_moved" msgid="266230079505650577">"स्क्रीन हलविली"</string>
+ <string name="action_resize" msgid="1802976324781771067">"आकार बदला"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"रूंदी वाढवा"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"उंची वाढवा"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"रुंदी कमी करा"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"उंची कमी करा"</string>
+ <string name="widget_resized" msgid="9130327887929620">"विजेटचा आकार रुंदी <xliff:g id="NUMBER_0">%1$s</xliff:g> उंची <xliff:g id="NUMBER_1">%2$s</xliff:g> मध्ये बदलला"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"शॉर्टकट"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> साठी <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> शॉर्टकट"</string>
+</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 7335605c8..756a2cf2f 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -19,35 +19,103 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="application_name" msgid="8424725141379931883">"Pelancar"</string>
- <string name="folder_name" msgid="8551881338202938211"></string>
- <string name="wallpaper_instructions" msgid="4215640646180727542">"Tetapkan kertas dinding"</string>
- <string name="pick_wallpaper" msgid="5630222540525626723">"Kertas dinding"</string>
- <string name="activity_not_found" msgid="217823393239365967">"Aplikasi tidak dipasang."</string>
- <string name="long_press_widget_to_add" msgid="7395697462851217506">"Sentuh &amp; tahan untuk mengambil widget."</string>
- <string name="widget_dims_format" msgid="1386418557719032947">"%1$d × %2$d"</string>
- <string name="out_of_space" msgid="8365249326091984698">"Tiada lagi ruang pada skrin Utama ini"</string>
- <string name="hotseat_out_of_space" msgid="6304886797358479361">"Tiada lagi ruang pada kerusi panas."</string>
- <string name="all_apps_button_label" msgid="2578400570124163469">"Apl"</string>
- <string name="all_apps_home_button_label" msgid="1022222300329398558">"Laman Utama"</string>
- <string name="delete_target_label" msgid="665300185123139530">"Alih keluar"</string>
- <string name="delete_target_uninstall_label" msgid="748894921183769150">"Nyahpasang"</string>
- <string name="info_target_label" msgid="4019495079517426980">"Maklumat apl"</string>
- <string name="permlab_install_shortcut" msgid="1201690825493376489">"pasang pintasan"</string>
- <string name="permdesc_install_shortcut" msgid="8634424803272077038">"Membenarkan aplikasi menambah pintasan tanpa campur tangan pengguna."</string>
- <string name="permlab_read_settings" msgid="3452408290738106747">"membaca tetapan dan pintasan Laman Utama"</string>
- <string name="permdesc_read_settings" msgid="5788109303585403679">"Membenarkan apl membaca tetapan dan pintasan di Laman Utama."</string>
- <string name="permlab_write_settings" msgid="1360567537236705628">"menulis tetapan dan pintasan Laman Utama"</string>
- <string name="permdesc_write_settings" msgid="8530105489115785531">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
- <string name="gadget_error_text" msgid="8359351016167075858">"Masalah memuatkan widget"</string>
- <string name="uninstall_system_app_text" msgid="6429814133777046491">"Ini adalah aplikasi sistem dan tidak boleh dinyahpasang."</string>
- <string name="folder_hint_text" msgid="8633351560105748141">"Folder Tanpa Nama"</string>
- <string name="default_scroll_format" msgid="4057140866420001240">"Halaman %1$d dari %2$d"</string>
- <string name="workspace_scroll_format" msgid="1704767047951143301">"Skrin utama %1$d dari %2$d"</string>
- <string name="folder_opened" msgid="1262064100943801533">"Folder dibuka, <xliff:g id="WIDTH">%1$d</xliff:g> kali <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="1335478160661137579">"Sentuh untuk menutup folder"</string>
- <string name="folder_tap_to_rename" msgid="5201612989905472442">"Sentuh untuk menyimpan penamaan semula"</string>
- <string name="folder_closed" msgid="3130534551370511932">"Folder ditutup"</string>
- <string name="folder_renamed" msgid="7951233572858053642">"Folder dinamakan semula kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format" msgid="3051680259794759037">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Kerja"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Apl tidak tersedia"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Apl yang dimuat turun dilumpuhkan dalam mod Selamat"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widget dilumpuhkan dalam mod Selamat"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Pintasan tidak tersedia"</string>
+ <string name="home_screen" msgid="806512411299847073">"Skrin utama"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Tindakan tersuai"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh &amp; tahan untuk mengambil widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketik dua kali &amp; 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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh &amp; tahan untuk meletakkan widget/ikon secara manual"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Tambahkan 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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cari lagi apl"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Tiada lagi ruang pada skrin Laman Utama ini."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Tiada ruang dalam dulang Kegemaran lagi"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Senarai apl"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Laman Utama"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Alih keluar"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Nyahpasang"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Maklumat apl"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"pasang pintasan"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Membenarkan apl menambah pintasan tanpa campur tangan pengguna."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"baca tetapan dan pintasan Laman Utama"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Membenarkan apl membaca tetapan dan pintasan di Laman Utama."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"tulis tetapan dan pintasan Laman Utama"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dibenarkan membuat panggilan telefon"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuatkan widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Persediaan"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini ialah apl sistem dan tidak boleh dinyahpasang."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> dilumpuhkan"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Halaman %1$d daripada %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Skrin Laman Utama %1$d daripada %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Halaman skrin utama baharu"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Folder dibuka, <xliff:g id="WIDTH">%1$d</xliff:g> kali <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Ketik untuk menutup folder"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ketik untuk menyimpan penamaan semula"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Folder ditutup"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Folder dinamakan semula kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Kertas dinding"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Tetapan"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Ikhtisar"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Apl ini tidak dipasang"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Apl untuk ikon ini tidak dipasang. Anda boleh mengalih keluar atau mencari dan memasang apl itu secara manual."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> memuat turun, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> menunggu untuk dipasang"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widget <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Tambahkan pada Skrin Utama"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Alihkan item ke sini"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Item ditambahkan pada skrin utama"</string>
+ <string name="item_removed" msgid="851119963877842327">"Item dialih keluar"</string>
+ <string name="action_move" msgid="4339390619886385032">"Alihkan Item"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Alihkan ke baris <xliff:g id="NUMBER_0">%1$s</xliff:g> lajur <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Alihkan ke kedudukan <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Alihkan ke kedudukan kegemaran <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Item dialihkan"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Tambahkan pada folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Tambahkan pada folder dengan <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Item ditambahkan pada folder"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Buat folder dengan: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Folder dibuat"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Alihkan ke Skrin Utama"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Alihkan skrin ke kiri"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Alihkan skrin ke kanan"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Skrin dialihkan"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Ubah saiz"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Tambahkan kelebaran"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Tambahkan ketinggian"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Kurangkan kelebaran"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Kurangkan ketinggian"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Saiz widget diubah menjadi <xliff:g id="NUMBER_0">%1$s</xliff:g> lebar <xliff:g id="NUMBER_1">%2$s</xliff:g> tinggi"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Pintasan"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pintasan untuk <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
new file mode 100644
index 000000000..449aae8e0
--- /dev/null
+++ b/res/values-my/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"ဖွင့်တင်စက်၃"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"အလုပ်"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"အက်ပ်မထည့်သွင်းထားပါ"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"အက်ပ်လက်လှမ်း မမှီပါ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ဒေါင်းလုဒ် အက်ပ်ကို လုံခြုံရေး မုဒ်ထဲမှာ ပိတ်ထား"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"လုံခြုံရေး မုဒ်ထဲမှာ ဝီဂျက်များကို ပိတ်ထား"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"ဖြတ်လမ်း မရနိုင်ပါ"</string>
+ <string name="home_screen" msgid="806512411299847073">"ပင်မစာမျက်နှာ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"စိတ်ကြိုက် လုပ်ဆောင်ချက်များ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ဝဒ်ဂျက်တစ်ခုကို ကောက်ယူရန် ဖိနှိပ်ထားပါ"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ကိုယ်တိုင်ထည့်ရန် ထိထားပါ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"အလိုအလျောက် ထည့်ရန်"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"အကြောင်းကြားချက်များ"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ဤပင်မမျက်နှာစာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"အနှစ်သက်ဆုံးများ ထားရာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"အက်ပ်စာရင်း"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ပင်မစာမျက်နှာ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ဖယ်ရှားမည်"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"ဖယ်ထုတ်မည်"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"အက်ပ်အချက်အလက်များ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"အသုံးပြုသူ လုပ်ဆောင်မှုမရှိပဲ အပ်ပလီကေးရှင်းကို အတိုကောက်မှတ်သားမှုများ ပြုလုပ်ခွင့် ပေးခြင်း"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ဖတ်ခြင်း"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ပင်မမျက်နှာစာတွင်ရှိသော အပြင်အဆင်နှင့် အတိုကောက်မှတ်သားမှုများကို အပ်ပလီကေးရှင်းအား ဖတ်ခွင့်ပြုခြင်း"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ရေးသားခြင်း"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ပင်မမျက်နှာစာတွင် ရှိသော အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများ ကို အပ်ပလီကေးရှင်းအား ပြောင်းခွင့်ပြုခြင်း"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>သည် ဖုန်းခေါ်ဆိုခွင့် မရှိပါ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ဝဒ်ဂျက် တင်ရာတွင် ပြသနာ ရှိပါသည်"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"စဖွင့်သတ်မှတ်ရန်"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ဤအပ်ပလီကေးရှင်းမှာ စစ်စတန်ပိုင်းဆိုင်ရာ အပ်ပလီကေးရှင်းဖြစ်ပါသည်။ ထုတ်ပစ်၍ မရပါ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"အမည်မရှိအကန့်"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ပိတ်ထားသည်"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"စာမျက်နှာ %1$d မှ %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"ပင်မစာမျက်နှာ %1$d မှ %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"ပင်မမျက်နှာပြင် စာမျက်နှာသစ်"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ဖွင့်ထားသောအကန့်, <xliff:g id="WIDTH">%1$d</xliff:g> နှင့် <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ဖိုင်တွဲကို ပိတ်ရန် တို့ပါ"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"အမည်ပြောင်းခြင်းကို သိမ်းဆည်းရန် တို့ပါ"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ပိတ်ထားသောအကန့်"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ပြောင်းလဲလိုက်သော အကန့်အမည် <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"အကန့်အမည်: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ဝိဂျက်များ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ဆက်တင်များ"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"ခြုံငုံသုံးသပ်ချက်"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ဖယ်ရှားရန်"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ရှာဖွေရန်"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"အက်ပ်မတပ်ဆင်ရသေးပါ"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ဤအိုင်ကွန်အတွက် အက်ပ်အားမထည့်သွင်းထားပါ။ You can remove it, or search for the အက်ပ်and install it manually."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ဒေါင်းလုဒ်လုပ်နေသည်၊ <xliff:g id="PROGRESS">%2$s</xliff:g> ပြီးပါပြီ"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ကိုထည့်သွင်းရန်စောင့်နေသည်"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ဝိဂျက်များ"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"ပင်မမျက်နှာစာသို့ ထည့်ပါ"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"၎င်းအား ဤသို့ ရွှေ့ပါ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ပင်မ ဖန်မျက်နှာပြင်သို့ ထည့်ပြီး၏"</string>
+ <string name="item_removed" msgid="851119963877842327">"၎င်းအား ဖယ်ရှားပြီး၏"</string>
+ <string name="action_move" msgid="4339390619886385032">"၎င်းအား ရွှေ့ပါ"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"အတန်း <xliff:g id="NUMBER_0">%1$s</xliff:g> အတိုင် <xliff:g id="NUMBER_1">%2$s</xliff:g> သို့ ရွှေ့ပါ"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> သို့ နေရာရွှေ့ပါ"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"စိတ်ကြိုက်နေရာ <xliff:g id="NUMBER">%1$s</xliff:g> သို့ ရွှေ့ပါ"</string>
+ <string name="item_moved" msgid="4606538322571412879">"၎င်းအားရွှေ့ပြီး"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ဖိုလ်ဒါသို့ ထည့်ရန်- <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> အမည်ရှိ ဖိုလ်ဒါသို့ ထည့်ပြီး၏"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ဖိုလ်ဒါသို့ ထည့်ပြီး"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ဖိုလ်ဒါ ပြုလုပ်ရန်- <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ဖိုလ်ဒါ ပြုလုပ်ပြီး"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"မျက်နှာပြင် ဘယ်ဘက်သို့ ရွှေ့ပါ"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"မျက်နှာပြင် ညာဘက်သို့ ရွှေ့ပါ"</string>
+ <string name="screen_moved" msgid="266230079505650577">"ဖန်မျက်နှာပြင် ပြောင်းရွှေ့ပြီး၏"</string>
+ <string name="action_resize" msgid="1802976324781771067">"အရွယ်အစားပြောင်းပါ"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"အကျယ်အား တိုးပါ"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"အမြင့်အား တိုးပါ"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"အကျယ်အား လျှော့ပါ"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"အမြင့်အား လျှော့ပါ"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Widget အား အကျယ် <xliff:g id="NUMBER_0">%1$s</xliff:g> အမြင့် <xliff:g id="NUMBER_1">%2$s</xliff:g> အရွယ်အစားပြန်လည်ချိန်ညှိပြီး၏"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"ဖြတ်လမ်းများ"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> အတွက် အမြန်နည်း <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ခု"</string>
+</resources>
diff --git a/res/values-ne/config.xml b/res/values-ne/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-ne/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
new file mode 100644
index 000000000..46c8f9cea
--- /dev/null
+++ b/res/values-ne/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"अनुप्रयोग स्थापित छैन।"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"अनुप्रयोग उपलब्ध छैन"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"सुरक्षित मोडमा डाउनलोड गरेको अनुप्रयोग अक्षम गरिएको छ"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"सुरक्षित मोडमा विगेटहरू अक्षम गरियो"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"सर्टकट उपलब्ध छैन"</string>
+ <string name="home_screen" msgid="806512411299847073">"गृह स्क्रिन"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"आफू अनुकूलका कारबाहीहरू"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"एउटा विजेटलाई टिप्नको लागि टच गरेर होल्ड गर्नुहोस्।"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"म्यानुअल तरिकाले थप्न छुनुहोस् र थिची राख्नुहोस्‌"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"स्वतः थप्नुहोस्"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप अनुप्रयोगहरू खोज्नुहोस्"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"मनपर्ने ट्रे अब कुनै ठाँउ छैन"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"अनुप्रयोगको सूची"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"गृह"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"हटाउनुहोस्"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"विस्थापित गर्नुहोस्"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"अनुप्रयोग जानकारी"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"सर्टकट स्थापना गर्नेहोस्"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा अनुप्रयोगलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"गृहमा एउटा अनुप्रयोगलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले फोन कलहरू गर्न अनुमति छैन"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"समस्या लोडिङ गर्ने विजेट"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"यो प्रणाली अनुप्रयोग हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"बेनाम फोल्डर"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"असक्षम पारिएको <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"पृष्ठ %2$d को %1$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"गृह स्क्रिन %1$d को %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"नयाँ गृह स्क्रिन पृष्ठ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"फोल्डर खुल्यो <xliff:g id="WIDTH">%1$d</xliff:g> बाट <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"फोल्डरलाई बन्द गर्न ट्याप गर्नुहोस्"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"पुनःनामाकरणलाई सुरक्षित गर्न ट्याप गर्नुहोस्"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"फोल्डर बन्द भयो"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"फोल्डर <xliff:g id="NAME">%1$s</xliff:g> मा पुनःनामाकरण गरियो।"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"विजेटहरू"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"वालपेपरहरु"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"सेटिंङहरू"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"परिदृश्य"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"आइकनको आकार परिवर्तन गर्नुहोस्"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"परिवर्तन नगर्नुहोस्"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"आइकनको आकारमा गरिएका परिवर्तनहरू लागू गरिँदैछन्"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"हटाउनुहोस्"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"खोजी गर्नुहोस्"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"यो अनुप्रयोग स्थापित छैन"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"यो प्रतिमाका लागि अनुप्रयोगलाई स्थापना गरिएको छैन। तपाईं यसलाई हटाउन, वा अनुप्रयोग खोजी र स्वयं यो स्थापित गर्न सक्नुहुन्छ।"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड गर्दै, <xliff:g id="PROGRESS">%2$s</xliff:g> सम्पन्‍न"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> स्थापना गर्न प्रतीक्षा गर्दै"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेटहरू"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"गृह स्क्रिनमा थप्नुहोस्"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"वस्तु यहाँ सार्नुहोस्"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"वस्तु गृह स्क्रिनमा थपियो"</string>
+ <string name="item_removed" msgid="851119963877842327">"वस्तु हटाइयो"</string>
+ <string name="action_move" msgid="4339390619886385032">"वस्तु सार्नुहोस्"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"पङ्क्ति <xliff:g id="NUMBER_0">%1$s</xliff:g> स्तम्भ <xliff:g id="NUMBER_1">%2$s</xliff:g> मा सार्नुहोस्"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"स्थिति <xliff:g id="NUMBER">%1$s</xliff:g> मा सार्नुहोस्"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"मनपर्ने स्थिति <xliff:g id="NUMBER">%1$s</xliff:g> मा सार्नुहोस्"</string>
+ <string name="item_moved" msgid="4606538322571412879">"वस्तु सारियो"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g> मा थप्नुहोस्"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"फोल्डरमा <xliff:g id="NAME">%1$s</xliff:g> सँग थप्नुहोस्"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"वस्तु फोल्डरमा थपियो"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"<xliff:g id="NAME">%1$s</xliff:g>: मार्फत फोल्डर सिर्जना गर्नुहोस्"</string>
+ <string name="folder_created" msgid="6409794597405184510">"फोल्डर सिर्जना गरियो"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"गृह स्क्रिनमा सार्नुहोस्"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"स्क्रिनलाई बायाँ सार्नुहोस्"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"स्क्रिनलाई दायाँ सार्नुहोस्"</string>
+ <string name="screen_moved" msgid="266230079505650577">"स्क्रिन सारियो"</string>
+ <string name="action_resize" msgid="1802976324781771067">"पुनःआकार मिलाउनुहोस्"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"चौडाइ बढाउनुहोस्"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"उँचाइ बढाउनुहोस्"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"चौडाइ घटाउनुहोस्"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"उँचाइ घटाउनुहोस्"</string>
+ <string name="widget_resized" msgid="9130327887929620">"विजेट चौडाइ <xliff:g id="NUMBER_0">%1$s</xliff:g> उचाइ <xliff:g id="NUMBER_1">%2$s</xliff:g> मा पुनः आकार मिलाइयो"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"सर्टकटहरू"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> का <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> सर्टकटहरू"</string>
+</resources>
diff --git a/res/values-pa/config.xml b/res/values-pa/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-pa/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
new file mode 100644
index 000000000..c4c11ce04
--- /dev/null
+++ b/res/values-pa/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ਦਫ਼ਤਰ"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ਡਾਊਨਲੋਡ ਕੀਤਾ ਐਪ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ਵਿਜਿਟ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"ਸ਼ਾਰਟਕੱਟ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="home_screen" msgid="806512411299847073">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਾਰਵਾਈਆਂ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਛੋਹਵੋT &amp; ਹੋਲਡ ਕਰੋ।"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ਡਬਲ-ਟੈਪ &amp; ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਹੋਲਡ ਕਰੋ ਅਤੇ ਕਸਟਮ ਕਿਰਿਆਵਾਂ ਵਰਤੋ।"</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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ਸਵੈਚਲਿਤ ਤਰੀਕੇ ਨਾਲ ਸ਼ਾਮਲ ਕਰੋ"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"ਸੂਚਨਾਵਾਂ"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ ਲਈ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ ਹੈ।"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"ਮਨਪਸੰਦ ਟ੍ਰੇ ਵਿੱਚ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ।"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"ਐਪ ਸੂਚੀ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ਹੋਮ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ਹਟਾਓ"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"ਸਥਾਪਨਾ ਰੱਦ ਕਰੋ"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ਐਪ ਜਾਣਕਾਰੀ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"ਸ਼ਾਰਟਕੱਟ ਇੰਸਟੌਲ ਕਰੋ"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"ਇੱਕ ਐਪ ਨੂੰ ਉਪਭੋਗਤਾ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹੋ"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਲਿਖੋ"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਫੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ਵਿਜੇਟ ਲੋਡ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ਸਥਾਪਤ ਕਰੋ"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ਇਹ ਇੱਕ ਸਿਸਟਮ ਐਪ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤਾ ਫੋਲਡਰ"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"ਸਫ਼ਾ %2$d ਦਾ %1$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"ਹੋਮ ਸਕ੍ਰੀਨ %2$d ਦੀ %1$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"ਨਵਾਂ ਹੋਮ ਸਕ੍ਰੀਨ ਸਫ਼ਾ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ਫੋਲਡਰ ਖੋਲ੍ਹਿਆ, <xliff:g id="WIDTH">%1$d</xliff:g> ਬਾਇ <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ਫੋਲਡਰ ਬੰਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"ਬਦਲੇ ਗਏ ਨਾਮ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ਫੋਲਡਰ ਬੰਦ ਕੀਤਾ"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ਫੋਲਡਰ ਨੂੰ <xliff:g id="NAME">%1$s</xliff:g> ਮੁੜ ਨਾਮ ਦਿੱਤਾ ਗਿਆ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ਵਿਜਿਟ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ਸੈਟਿੰਗਾਂ"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"ਰੂਪ-ਰੇਖਾ"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"ਨਾ ਬਦਲੋ"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"ਅਗਿਆਤ"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ਹਟਾਓ"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ਖੋਜੋ"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"ਇਹ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ਇਸ ਆਈਕਨ ਲਈ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਖੋਜ ਸਕਦੇ ਹੋ ਅਤੇ ਇਸਨੂੰ ਮੈਨੂਅਲੀ ਇੰਸਟੌਲ ਕਰ ਸਕਦੇ ਹੋ।"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ਡਾਉਨਲੋਡ ਹੋਰ ਰਿਹਾ ਹੈ, <xliff:g id="PROGRESS">%2$s</xliff:g> ਸੰਪੂਰਣ"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ਸਥਾਪਿਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ਵਿਜਿਟ"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜੋ"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"ਆਈਟਮ ਨੂੰ ਇੱਥੇ ਮੂਵ ਕਰੋ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ਆਈਟਮ ਨੂੰ ਮੁੱਖ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"</string>
+ <string name="item_removed" msgid="851119963877842327">"ਅਈਟਮ ਹਟਾਈ ਗਈ"</string>
+ <string name="action_move" msgid="4339390619886385032">"ਆਈਟਮ ਨੂੰ ਮੂਵ ਕਰੋ"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"ਕਤਾਰ <xliff:g id="NUMBER_0">%1$s</xliff:g> ਕਾਲਮ <xliff:g id="NUMBER_1">%2$s</xliff:g> ਵਿੱਚ ਮੂਵ ਕਰੋ"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"ਸਥਿਤੀ <xliff:g id="NUMBER">%1$s</xliff:g> ਵਿੱਚ ਮੂਵ ਕਰੋ"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ਮਨਪਸੰਦ ਸਥਿਤੀ <xliff:g id="NUMBER">%1$s</xliff:g> ਵਿੱਚ ਮੂਵ ਕਰੋ"</string>
+ <string name="item_moved" msgid="4606538322571412879">"ਆਈਟਮ ਮੂਵ ਕੀਤੀ ਗਈ"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ਇਸ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜੋ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ਦੇ ਨਾਲ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜੋ"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"ਆਈਟਮ ਨੂੰ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ਇਸਦੇ ਨਾਲ ਫੋਲਡਰ ਬਣਾਓ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ਫੋਲਡਰ ਬਣਾਇਆ ਗਿਆ"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ਮੁੱਖ ਸਕ੍ਰੀਨ ਵਿੱਚ ਮੂਵ ਕਰੋ"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"ਸਕ੍ਰੀਨ ਨੂੰ ਖੱਬੇ ਮੂਵ ਕਰੋ"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"ਸਕ੍ਰੀਨ ਨੂੰ ਸੱਜੇ ਮੂਵ ਕਰੋ"</string>
+ <string name="screen_moved" msgid="266230079505650577">"ਸਕ੍ਰੀਨ ਨੂੰ ਮੂਵ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="action_resize" msgid="1802976324781771067">"ਮੁੜ ਆਕਾਰ ਦਿਓ"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"ਚੌੜਾਈ ਵਧਾਓ"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"ਉਂਚਾਈ ਵਧਾਓ"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"ਚੌੜਾਈ ਘਟਾਓ"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"ਉਂਚਾਈ ਘਟਾਓ"</string>
+ <string name="widget_resized" msgid="9130327887929620">"ਵਿਜੈਟ ਨੂੰ ਚੌੜਾਈ <xliff:g id="NUMBER_0">%1$s</xliff:g> ਉਂਚਾਈ <xliff:g id="NUMBER_1">%2$s</xliff:g> ਨੂੰ ਮੁੜ ਆਕਾਰ ਦਿੱਤਾ"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"ਸ਼ਾਰਟਕੱਟ"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ਸ਼ਾਰਟਕੱਟ"</string>
+</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
new file mode 100644
index 000000000..569a77f00
--- /dev/null
+++ b/res/values-si/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"කාර්යාලය"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"යෙදුම ස්ථාපනය කර නැත."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"යෙදුම නොතිබේ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ආරක්ෂිත ආකාරය තුළ බාගන්න ලද යෙදුම් අබල කරන්න"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"සුරක්ෂිත ආකාරය තුළ විජටය අබල කරන ලදි"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"කෙටි මග ලබා ගත නොහැකිය"</string>
+ <string name="home_screen" msgid="806512411299847073">"මුල් පිටු තිරය"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"අභිරුචි ක්‍රියා"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"විජට් එක ස්පර්ශ කර අහුලා ගැනීමට අල්ලාගෙන සිටින්න."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"අතින් ස්ථානගත කිරීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ස්වයංක්‍රියව එක් කරන්න"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"දැනුම්දීම්"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"මෙම මුල් පිටු තිරය මත තවත් අවසර නැත."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"ප්‍රියතම දෑ ඇති තැටියේ තවත් ඉඩ නොමැත"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"යෙදුම් ලැයිස්තුව"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"මුල් පිටුව"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ඉවත් කරන්න"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"අස්ථාපනය කරන්න"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"යෙදුම් තොරතුරු"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"කෙටිමං ස්ථාපනය කරන්න"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමකට අවසර දෙයි."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"මුල් පිටු සැකසීම් සහ කෙටිමං කියවන්න"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"මුල් පිටුවේ ඇති සැකසීම් සහ කෙටිමං කියවීමට යෙදුමකට අවසර දෙයි."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"මුල් පිටු සැකසීම් සහ කෙටිමං ලියන්න"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"මුල් පිටුවේ සැකසීම් සහ කෙටිමං ඉවත් කිරීමට යෙදුමට අවසර දෙයි."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> හට දුරකථන ඇමතුම් සිදු කිරීමට ඉඩ නොදේ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ගැටලු පූරණ විජට් එක"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ස්ථාපනය කරන්න"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"මෙය පද්ධති යෙදුමක් වන අතර අස්ථාපනය කළ නොහැක."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"නම් නොකළ ෆෝල්ඩරය"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> අබල කෙරිණි"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d හි %1$d පිටුව"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"මුල් පිටු තිරය %2$d හි %1$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"නව මුල් පිටුව"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ෆෝල්ඩරය විවෘත විය, <xliff:g id="WIDTH">%1$d</xliff:g> හි <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ෆෝල්ඩරය වැසීමට තට්ටු කරන්න"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"යළි නම් කිරීම සුරැකීමට තට්ටු කරන්න"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ෆෝල්ඩරය වසා ඇත"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"<xliff:g id="NAME">%1$s</xliff:g> වෙත ෆෝල්ඩරය නැවත නම් කෙරිණි"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ෆෝල්ඩරය: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"විජට්"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"වෝල්පේපර"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"සැකසීම්"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"දළ විශ්ලේෂණය"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"නොදනී"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ඉවත් කරන්න"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"සොයන්න"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"මෙම යෙදුම ස්ථාපනය කර නොමැත"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"මෙම නිරුපකයට යෙදුම ස්ථාපනය කර නොමැත. ඔබට එය ඉවත් කළ හැක, හෝ යෙදුම් සඳහා සොයන්න සහ අතින් ස්ථාපනය කරන්න."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> බාගත කරමින්, <xliff:g id="PROGRESS">%2$s</xliff:g> සම්පූර්ණයි"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ස්ථාපනය කිරීමට බලා සිටිමින්"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> විජට්"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"මුල් තිරය වෙත එක් කරන්න"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"මෙතනට අයිතමය ගෙන එන්න"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"අයිතමය මුල් තිරය වෙත එකතු කරන ලදි"</string>
+ <string name="item_removed" msgid="851119963877842327">"අයිතමය ඉවත් කරන ලදි"</string>
+ <string name="action_move" msgid="4339390619886385032">"අයිතමය ගෙනයන්න"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"පේළිය <xliff:g id="NUMBER_0">%1$s</xliff:g> තීරුව <xliff:g id="NUMBER_1">%2$s</xliff:g> වෙත ගෙන යන්න"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> ස්ථානය වෙත ගෙන යන්න"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ප්‍රියතම ස්ථානය <xliff:g id="NUMBER">%1$s</xliff:g> වෙත ගෙන යන්න"</string>
+ <string name="item_moved" msgid="4606538322571412879">"අයිතමය ගෙන යන ලදි"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ෆෝල්ඩරය එක් කරන්න: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> සමඟ ෆෝල්ඩරය වෙත එක් කරන්න"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"අයිතමය ෆෝඩරය වෙතට එක් කරන ලදි"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"මේ සමග ෆෝල්ඩරය සාදන්න: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ෆෝල්ඩරය සාදන ලදි"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"මුල් තිරය වෙත ගෙන යන්න"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"තිරය වම් පැත්තට ගෙනයන්න"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"තිරය දකුණු පැත්තට ගෙනයන්න"</string>
+ <string name="screen_moved" msgid="266230079505650577">"තිරය ගෙන යන ලදි"</string>
+ <string name="action_resize" msgid="1802976324781771067">"නැවත ප්‍රමාණගත කිරීම"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"පළල වැඩි කරන්න"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"උස වැඩි කරන්න"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"පළල අඩු කරන්න"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"උස අඩු කරන්න"</string>
+ <string name="widget_resized" msgid="9130327887929620">"විජට් පළල <xliff:g id="NUMBER_0">%1$s</xliff:g> උස <xliff:g id="NUMBER_1">%2$s</xliff:g> වෙත ප්‍රමාණකරණය කරන ලදි"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"කෙටිමං"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> සඳහා කෙටි මං <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
+</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
new file mode 100644
index 000000000..2b656840d
--- /dev/null
+++ b/res/values-sq/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Nisësi3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Puna"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Aplikacioni nuk është i instaluar."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikacioni nuk mundësohet"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplikacioni i shkarkuar është i çaktivizuar në modalitetin e sigurt"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Miniaplikacionet janë të çaktivizuara në modalitetin e sigurt"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Shkurtorja nuk është e disponueshme"</string>
+ <string name="home_screen" msgid="806512411299847073">"Ekrani bazë"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Veprimet e personalizuara"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Prek dhe mbaj shtypur për të zgjedhur një miniaplikacion."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Prek dhe mbaj të shtypur për të vendosur në mënyrë manuale"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Shto 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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Nuk ka më hapësirë në këtë ekran bazë."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Nuk ka më hapësirë në tabakanë \"Të preferuarat\""</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Lista e aplikacioneve"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Faqja kryesore"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Hiqe"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Çinstalo"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Informacion mbi aplikacionin"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalo shkurtore"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Lejon një aplikacion të shtojë shkurtore pa ndërhyrjen e përdoruesit."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"lexo cilësimet dhe shkurtoret e ekranit bazë"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Lejon aplikacionin të lexojë cilësimet dhe shkurtoret në ekranin bazë."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"shkruaj cilësimet dhe shkurtoret e ekranit bazë"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Lejon aplikacionin të ndryshojë cilësimet dhe shkurtoret në ekranin bazë."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk lejohet të kryejë telefonata"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem në ngarkimin e miniaplikacionit"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguro"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ky është aplikacion sistemi dhe nuk mund të çinstalohet."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Dosje e paemërtuar"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> u çaktivizua"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"Faqja: %1$d nga gjithsej %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Ekrani bazë: %1$d nga gjithsej %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Faqja e ekranit të ri kryesor"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Dosja u hap, <xliff:g id="WIDTH">%1$d</xliff:g> me <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Trokit për të mbyllur dosjen"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"Trokit për të ruajtur riemërtimin"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Dosja u mbyll"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Dosja u riemërtua në <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikacionet"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Imazhet e sfondit"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Cilësimet"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Përmbledhje"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikacioni nuk është i instaluar"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacioni për këtë ikonë nuk është i instaluar. Mund ta heqësh ose të kërkosh aplikacionin dhe ta instalosh atë në mënyrë manuale."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> po shkarkohet, <xliff:g id="PROGRESS">%2$s</xliff:g> të përfunduara"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> po pret të instalohet"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Miniaplikacionet e <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Shto në Ekranin bazë"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Zhvendose artikullin këtu"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Artikulli u shtua tek ekrani bazë"</string>
+ <string name="item_removed" msgid="851119963877842327">"Artikulli u hoq"</string>
+ <string name="action_move" msgid="4339390619886385032">"Zhvendose artikullin"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"Zhvendos te rreshti <xliff:g id="NUMBER_0">%1$s</xliff:g>, kolona <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"Zhvendos te pozicioni <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Zhvendos te pozicioni <xliff:g id="NUMBER">%1$s</xliff:g> i preferencave"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Artikulli u zhvendos"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Shto te dosja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Shto te dosja me <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Artikulli u shtua te dosja"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Krijo një dosje me: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Dosja u krijua"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Zhvendose në Ekranin bazë"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Zhvendose ekranin në të majtë"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Zhvendose ekranin në të djathtë"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Ekrani u zhvendos"</string>
+ <string name="action_resize" msgid="1802976324781771067">"Ndrysho madhësinë"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Rrit gjerësinë"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Rrit lartësinë"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Zvogëlo gjerësinë"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Zvogëlo lartësinë"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Madhësia e miniaplikacionit u ndryshua me gjerësinë <xliff:g id="NUMBER_0">%1$s</xliff:g> dhe lartësinë <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Shkurtoret"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> shkurtesa për <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index de809b105..bc65a0e9a 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -26,6 +26,7 @@
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
+ <item name="android:keyboardLayout">@layout/all_apps_search_container</item>
</style>
<!-- Workspace -->
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
new file mode 100644
index 000000000..a1e00a11d
--- /dev/null
+++ b/res/values-ta/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"பணியிடம்"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"பயன்பாடு இல்லை"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"இறக்கிய பயன்பாடு பாதுகாப்பு முறையில் முடக்கப்பட்டது"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"குறுக்குவழி இல்லை"</string>
+ <string name="home_screen" msgid="806512411299847073">"முகப்புத் திரை"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"தனிப்பயன் செயல்கள்"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் பிடிக்கவும்."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"தானாகவே சேர்"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"அறிவிப்புகள்"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"பிடித்தவை ட்ரேயில் இடமில்லை"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"பயன்பாடுகளின் பட்டியல்"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"முகப்பு"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"அகற்று"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"நிறுவல் நீக்கு"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"பயன்பாட்டுத் தகவல்"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"குறுக்குவழிகளை நிறுவுதல்"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"ஃபோன் அழைப்புகள் செய்ய, <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதிக்கப்படவில்லை"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"விட்ஜெட்டை ஏற்றுவதில் சிக்கல்"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"அமைவு"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"பெயரிடப்படாத கோப்புறை"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> முடக்கப்பட்டது"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"பக்கம் %1$d / %2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"முகப்புத் திரை %1$d of %2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"புதிய முகப்புத் திரை பக்கம்"</string>
+ <string name="folder_opened" msgid="94695026776264709">"திறக்கப்பட்டக் கோப்புறை, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"கோப்புறையை மூட, தட்டவும்"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"மாற்றிய பெயரைச் சேமிக்க, தட்டவும்"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"கோப்புறை மூடப்பட்டது"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"கோப்புறை <xliff:g id="NAME">%1$s</xliff:g> என மறுபெயரிடப்பட்டது"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ஷார்ட்கட்ஸ்"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"அமைப்பு"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"மேலோட்டப் பார்வை"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <string name="package_state_unknown" msgid="7592128424511031410">"தெரியாதது"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"அகற்று"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"தேடு"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"பயன்பாடு நிறுவப்படவில்லை"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ஐகானுக்கான பயன்பாடு நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>ஐப் பதிவிறக்குகிறது, <xliff:g id="PROGRESS">%2$s</xliff:g> முடிந்தது"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>ஐ நிறுவுவதற்காகக் காத்திருக்கிறது"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> விட்ஜெட்டுகள்"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"முகப்புத் திரையில் சேர்"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"இங்கு நகர்த்து"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"முகப்புத் திரையில் சேர்க்கப்பட்டது"</string>
+ <string name="item_removed" msgid="851119963877842327">"அகற்றப்பட்டது"</string>
+ <string name="action_move" msgid="4339390619886385032">"நகர்த்து"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> வரிசை, <xliff:g id="NUMBER_1">%2$s</xliff:g> நெடுவரிசைக்கு நகர்த்து"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"நிலை <xliff:g id="NUMBER">%1$s</xliff:g>க்கு நகர்த்து"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"விரும்பும் நிலை <xliff:g id="NUMBER">%1$s</xliff:g>க்கு நகர்த்து"</string>
+ <string name="item_moved" msgid="4606538322571412879">"உருப்படி நகர்த்தப்பட்டது"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"இந்தக் கோப்புறையில் சேர்க்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> உள்ள கோப்புறையில் சேர்க்கும்"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"கோப்புறையில் உருப்படி சேர்க்கப்பட்டது"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"இதனுடன் கோப்புறையை உருவாக்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"கோப்புறை உருவாக்கப்பட்டது"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"முகப்புத் திரைக்கு நகர்த்து"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"திரையை இடப்புறம் நகர்த்து"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"திரையை வலப்புறம் நகர்த்து"</string>
+ <string name="screen_moved" msgid="266230079505650577">"திரை நகர்த்தப்பட்டது"</string>
+ <string name="action_resize" msgid="1802976324781771067">"அளவு மாற்று"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"அகலத்தை அதிகரி"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"உயரத்தை அதிகரி"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"அகலத்தைக் குறை"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"உயரத்தைக் குறை"</string>
+ <string name="widget_resized" msgid="9130327887929620">"அகலம் <xliff:g id="NUMBER_0">%1$s</xliff:g> மற்றும் உயரம் <xliff:g id="NUMBER_1">%2$s</xliff:g>க்கு விட்ஜெட் அளவு மாற்றப்பட்டது"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"குறுக்குவழிகள்"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>க்கான <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> குறுக்குவழிகள்"</string>
+</resources>
diff --git a/res/values-te/config.xml b/res/values-te/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-te/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
new file mode 100644
index 000000000..65ca92775
--- /dev/null
+++ b/res/values-te/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"కార్యాలయం"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"అనువర్తనం అందుబాటులో లేదు"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"డౌన్‌లోడ్ చేసిన అనువర్తనం సురక్షిత మోడ్‌లో నిలిపివేయబడింది"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"సురక్షిత మోడ్‌లో విడ్జెట్‌లు నిలిపివేయబడ్డాయి"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"సత్వరమార్గం అందుబాటులో లేదు"</string>
+ <string name="home_screen" msgid="806512411299847073">"హోమ్ స్క్రీన్"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"అనుకూల చర్యలు"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"విడ్జెట్‌ను ఎంచుకోవడానికి తాకి &amp; నొక్కి పెట్టండి."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"మాన్యువల్‌గా ఉంచడానికి నొక్కి &amp;amp పట్టుకోండి"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"స్వయంచాలకంగా జోడించు"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని అనువర్తనాల కోసం శోధించు"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్‌లు"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ఈ హోమ్ స్క్రీన్‌లో ఖాళీ లేదు."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"ఇష్టమైనవి ట్రేలో ఖాళీ లేదు"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"అనువర్తనాల జాబితా"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"హోమ్"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"తీసివేయి"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"అన్ఇన్‌స్టాల్ చేయి"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"అనువర్తన సమాచారం"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"సత్వరమార్గాలను ఇన్‌స్టాల్ చేయడం"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడం"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్‌లను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"విడ్జెట్‌ను లోడ్ చేయడంలో సమస్య"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"సెటప్ చేయి"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ అనువర్తనం మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> నిలిపివేయబడింది"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$dలో %1$dవ పేజీ"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dలో %1$dవ హోమ్ స్క్రీన్"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"కొత్త హోమ్ స్క్రీన్ పేజీ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ఫోల్డర్ తెరవబడింది, <xliff:g id="WIDTH">%1$d</xliff:g> X <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"ఫోల్డర్‌ను మూసివేయడానికి నొక్కండి"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"పేరు మార్పును సేవ్ చేయడానికి నొక్కండి"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"ఫోల్డర్ మూసివేయబడింది"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"ఫోల్డర్ పేరు <xliff:g id="NAME">%1$s</xliff:g>గా మార్చబడింది"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"విడ్జెట్‌లు"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"వాల్‌పేపర్‌లు"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"సెట్టింగ్‌లు"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"స్థూలదృష్టి"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"చిహ్న ఆకారాన్ని మార్చు"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"మార్చవద్దు"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"చిహ్న ఆకార మార్పులను వర్తింపజేస్తోంది"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"తెలియదు"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"తీసివేయి"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"శోధించు"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"ఈ అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ఈ చిహ్నం యొక్క అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ అనువర్తనం కోసం శోధించి దాన్ని మాన్యువల్‌గా ఇన్‌స్టాల్ చేయవచ్చు."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> డౌన్‌లోడ్ అవుతోంది, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ఇన్‌స్టాల్ కావడానికి వేచి ఉంది"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> విడ్జెట్‌లు"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"హోమ్ స్క్రీన్‌కు జోడించు"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"అంశాన్ని ఇక్కడికి తరలించు"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"అంశం హోమ్‌స్క్రీన్‌కి జోడించబడింది"</string>
+ <string name="item_removed" msgid="851119963877842327">"అంశం తీసివేయబడింది"</string>
+ <string name="action_move" msgid="4339390619886385032">"అంశాన్ని తరలించు"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"అడ్డు వరుస <xliff:g id="NUMBER_0">%1$s</xliff:g> నిలువు వరుస <xliff:g id="NUMBER_1">%2$s</xliff:g>కి తరలించు"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g>వ స్థానానికి తరలించు"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"ఇష్టమైనవిలో <xliff:g id="NUMBER">%1$s</xliff:g>వ స్థానానికి తరలించు"</string>
+ <string name="item_moved" msgid="4606538322571412879">"అంశం తరలించబడింది"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"ఈ ఫోల్డర్‌కి జోడించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> గల ఫోల్డర్‌కు జోడించు"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"అంశం ఫోల్డర్‌కు జోడించబడింది"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను సృష్టించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"ఫోల్డర్ సృష్టించబడింది"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"హోమ్‌స్క్రీన్‌కు తరలించు"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"స్క్రీన్‌ను ఎడమవైపుకి జరుపు"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"స్క్రీన్‌ను కుడివైపుకి జరుపు"</string>
+ <string name="screen_moved" msgid="266230079505650577">"స్క్రీన్ జరపబడింది"</string>
+ <string name="action_resize" msgid="1802976324781771067">"పరిమాణం మార్చు"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"వెడల్పును పెంచు"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"ఎత్తును పెంచు"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"వెడల్పును తగ్గించు"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"ఎత్తును తగ్గించు"</string>
+ <string name="widget_resized" msgid="9130327887929620">"విడ్జెట్ పరిమాణం వెడల్పు <xliff:g id="NUMBER_0">%1$s</xliff:g>కి, ఎత్తు <xliff:g id="NUMBER_1">%2$s</xliff:g>కి మార్చబడింది"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"సత్వరమార్గాలు"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> కోసం <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> సత్వరమార్గాలు"</string>
+</resources>
diff --git a/res/values-ur/config.xml b/res/values-ur/config.xml
new file mode 100644
index 000000000..56f98c356
--- /dev/null
+++ b/res/values-ur/config.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="icon_shape_override_paths_values">
+ <item msgid="6640290598899495380"></item>
+ <item msgid="4009824731445917273">"M50,0L100,0 100,100 0,100 0,0z"</item>
+ <item msgid="3964229851574011244">"M50,0L80,0 A20,20,0,0 1 100,20 L100,80 A20,20,0,0 1 80,100 L20,100 A20,20,0,0 1 0,80 L 0,20 A20,20,0,0 1 20,0z"</item>
+ <item msgid="363553284746233331">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</item>
+ <item msgid="4319038504053267455">"M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"</item>
+ <item msgid="483370082941112059">"M50,0A50,30 0,0,1 100,30V70A50,30 0,0,1 0,70V30A50,30 0,0,1 50,0z"</item>
+ </string-array>
+ <!-- no translation found for icon_shape_override_paths_names:0 (4837899951986816538) -->
+</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
new file mode 100644
index 000000000..29d1cd53c
--- /dev/null
+++ b/res/values-ur/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"دفتری"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"ایپ انسٹال نہیں ہے۔"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ایپ دستیاب نہیں ہے"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ڈاؤن لوڈ کردہ ایپ کو محفوظ وضع میں غیر فعال کر دیا گیا"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ویجیٹس کو محفوظ وضع میں غیر فعال کر دیا گیا"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"شارٹ کٹ دستیاب نہیں ہے"</string>
+ <string name="home_screen" msgid="806512411299847073">"ہوم اسکرین"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"حسب ضرورت کارروائیاں"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"کوئی ویجیٹ منتخب کرنے کیلئے ٹچ کریں اور پکڑے رہیں۔"</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"‏دستی طور پر رکھنے کیلئے ‎&amp; ٹچ کرکے ہولڈ کریں"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"خود کار طور پر شامل کریں"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"اطلاعات"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"اس ہوم اسکرین پر مزید کوئی گنجائش نہیں ہے۔"</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"پسندیدہ ٹرے میں مزید کوئی گنجائش نہیں ہے"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"ایپس کی فہرست"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ہوم"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"ہٹائیں"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"اَن انسٹال کریں"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ایپ کی معلومات"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"شارٹ کٹس انسٹال کریں"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"کسی ایپ کو صارف کی مداخلت کے بغیر شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ہوم ترتیبات اور شارٹ کٹس کو پڑھیں"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو پڑھنے کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ہوم ترتیبات اور شارٹ کٹس کو لکھیں"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت دیتا ہے۔"</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو فون کالیں کرنے کی اجازت نہیں ہے"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ویجیٹ کو لوڈ کرنے میں مسئلہ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ترتیب دیں"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"یہ ایک سسٹم ایپ ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"بلا نام فولڈر"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیر فعال ہے"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"‏صفحہ ‎%1$d از ‎%2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"‏ہوم اسکرین ‎%1$d از ‎%2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"نیا ہوم اسکرین صفحہ"</string>
+ <string name="folder_opened" msgid="94695026776264709">"فولڈر کھولا گیا، <xliff:g id="WIDTH">%1$d</xliff:g> × <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"فولڈر کو بند کرنے کیلئے تھپتھپائیں"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"نام کی تبدیلی محفوظ کرنے کیلئے تھپتھپائیں"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"فولڈر بند ہو گیا"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"فولڈر کا نام تبدیل کر کے <xliff:g id="NAME">%1$s</xliff:g> کر دیا گیا"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ویجیٹس"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"وال پیپرز"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"ترتیبات"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"مجموعی جائزہ"</string>
+ <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="icon_shape_override_label" msgid="2977264953998281004">"آئیکن کی شکل تبدیل کریں"</string>
+ <string name="icon_shape_no_override" msgid="3678524428085518367">"تبدیل نہ کریں"</string>
+ <string name="icon_shape_override_progress" msgid="3461735694970239908">"آئيکن کی شکل کی تبدیلیاں لاگو ہو رہی ہیں"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"نامعلوم"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ہٹائیں"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"تلاش کریں"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"یہ ایپ انسٹال کردہ نہیں ہے"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"اس آئیکن کیلئے ایپ انسٹال کردہ نہیں ہے۔ آپ اسے ہٹا سکتے ہیں یا ایپ کو تلاش کر سکتے اور دستی طور پر اسے انسٹال کر سکتے ہیں۔"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ڈاؤن لوڈ ہو رہا ہے، <xliff:g id="PROGRESS">%2$s</xliff:g> مکمل ہو گیا"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> انسٹال ہونے کا انتظار کر رہی ہے"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ویجیٹس"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"ہوم اسکرین میں شامل کریں"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"آئٹم یہاں منتقل کریں"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"آئٹم کو ہوم اسکرین میں شامل کر دیا گیا"</string>
+ <string name="item_removed" msgid="851119963877842327">"آئٹم ہٹا دیا گیا"</string>
+ <string name="action_move" msgid="4339390619886385032">"آئٹم منتقل کریں"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"قطار <xliff:g id="NUMBER_0">%1$s</xliff:g> کالم <xliff:g id="NUMBER_1">%2$s</xliff:g> میں منتقل کریں"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"پوزیشن <xliff:g id="NUMBER">%1$s</xliff:g> میں منتقل کریں"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"پسندیدہ پوزیشن <xliff:g id="NUMBER">%1$s</xliff:g> میں منتقل کریں"</string>
+ <string name="item_moved" msgid="4606538322571412879">"آئٹم منتقل کر دیا گیا"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"فولڈر میں شامل کریں: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> کے فولڈر میں شامل کریں"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"آئٹم فولڈر میں شامل کر دیا گیا"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"اس کے ساتھ فولڈر بنائیں: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"فولڈر بنا دیا گیا"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"ہوم اسکرین میں منتقل کریں"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"اسکرین کو بائیں منتقل کریں"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"اسکرین کو دائیں منتقل کریں"</string>
+ <string name="screen_moved" msgid="266230079505650577">"اسکرین منتقل کر دی گئی"</string>
+ <string name="action_resize" msgid="1802976324781771067">"سائز تبدیل کریں"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"چوڑائی بڑھائیں"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"اونچائی بڑھائیں"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"چوڑائی کم کریں"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"اونچائی کم کریں"</string>
+ <string name="widget_resized" msgid="9130327887929620">"ویجیٹ کے سائز کو چوڑائی <xliff:g id="NUMBER_0">%1$s</xliff:g> اونچائی <xliff:g id="NUMBER_1">%2$s</xliff:g> میں تبدیل کر دیا گیا"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"شارٹ کٹس"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> کیلئے <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> شارٹ کٹس"</string>
+</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
new file mode 100644
index 000000000..81be979cc
--- /dev/null
+++ b/res/values-uz/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Ishga oid"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Ilova o‘rnatilmadi."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Ilova mavjud emas"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Yuklab olingan ilova xavfsiz rejimda o‘chirib qo‘yildi"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Xavfsiz rejimda vidjetlar o‘chirib qo‘yilgan"</string>
+ <string name="shortcut_not_available" msgid="2536503539825726397">"Tezkor tugmadan foydalanib bo‘lmaydi"</string>
+ <string name="home_screen" msgid="806512411299847073">"Bosh ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Maxsus amallar"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidjetni tanlash uchun bosib turing."</string>
+ <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>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Qo‘lda joylashtirish uchun bosib turing"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Avtomatik chiqarish"</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>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Uy ekranida bitta ham xona yo‘q."</string>
+ <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ajratilganlarda birorta ham xona yo‘q"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Ilovalar ro‘yxati"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Bosh sahifa"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Olib tashlash"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"O‘chirib tashlash"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Ilova haqida"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"yorliqlar yaratish"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ilovalarga foydalanuvchidan so‘ramasdan yorliqlar qo‘shishga ruxsat beradi."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"Uy sozlamalari va yorliqlarini o‘qish"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalarni o‘qish uchun ruxsat beradi."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"Uy sozlamalari va yorliqlarini yozish"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalrni o‘zgartirish uchun ruxsat beradi."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga qo‘ng‘iroqlarni amalga oshirishga ruxsat berilmagan"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Vidjetni yuklashda muammo"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Sozlash"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Nomsiz jild"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi o‘chirib qo‘yildi"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$ddan %1$d ta sahifa"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"Uy ekrani %2$ddan %1$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"Yangi bosh ekran sahifasi"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Jild ochildi, <xliff:g id="WIDTH">%1$d</xliff:g> ga <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Jildni yopish uchun ustiga bosing"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"O‘zgarishni saqlash uchun ustiga bosing"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Jild yopildi"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Jild nomi <xliff:g id="NAME">%1$s</xliff:g>ga o‘zgartirildi"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Jild: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidjetlar"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Fon rasmlari"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"Sozlamalar"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
+ <string name="accessibility_action_overview" msgid="6257665857640347026">"Umumiy ko‘rinish"</string>
+ <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>
+ <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+ <skip />
+ <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+ <skip />
+ <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+ <skip />
+ <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>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Ushbu ilova o‘rnatilmagan"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ilova o‘rnatilmagan. Belgini o‘chirib tashlashingiz yoki ilovani topib, uni qo‘lda o‘rnatishingiz mumkin."</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> yuklab olinmoqda, <xliff:g id="PROGRESS">%2$s</xliff:g> bajarildi"</string>
+ <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi o‘rnatilishi kutilmoqda"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> vidjetlari"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Bosh ekranga qo‘shish"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"Obyektni bu yerga ko‘chirish"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"Obyekt bosh ekranga qo‘shildi"</string>
+ <string name="item_removed" msgid="851119963877842327">"Obyekt o‘chirib tashlandi"</string>
+ <string name="action_move" msgid="4339390619886385032">"Obyektni ko‘chirib o‘tkazish"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> <xliff:g id="NUMBER_1">%2$s</xliff:g> katakka ko‘chirib o‘tkazish"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g>-joyga ko‘chirib o‘tkazish"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Sevimlilarga (<xliff:g id="NUMBER">%1$s</xliff:g>) ko‘chirib o‘tkazish"</string>
+ <string name="item_moved" msgid="4606538322571412879">"Element ko‘chirib o‘tkazildi"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"<xliff:g id="NAME">%1$s</xliff:g> jildiga qo‘shish"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi bor jildga qo‘shish"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Element jildga qo‘shildi"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"<xliff:g id="NAME">%1$s</xliff:g> bilan jild yaratish"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Jild yaratildi"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"Bosh ekranga ko‘chirish"</string>
+ <string name="action_move_screen_left" msgid="8854216831569401665">"Ekranni chapga siljitish"</string>
+ <string name="action_move_screen_right" msgid="329334910274311123">"Ekranni o‘ngga siljitish"</string>
+ <string name="screen_moved" msgid="266230079505650577">"Ekran siljitildi"</string>
+ <string name="action_resize" msgid="1802976324781771067">"O‘lchamini o‘zgartirish"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"Enini uzaytirish"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"Bo‘yini uzaytirish"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"Enini kichraytirish"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"Bo‘yini kichraytirish"</string>
+ <string name="widget_resized" msgid="9130327887929620">"Vidjetning eni <xliff:g id="NUMBER_0">%1$s</xliff:g>, bo‘yi <xliff:g id="NUMBER_1">%2$s</xliff:g> qilib o‘zgartirildi"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Tezkor tugmalar"</string>
+ <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ilovasi uchun <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ta tezkor tugma"</string>
+</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 18f409f34..18759f817 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -16,7 +16,7 @@
*/
-->
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
@@ -111,4 +111,8 @@
</attr>
</declare-styleable>
+ <declare-styleable name="ShadowDrawable">
+ <attr name="android:src" />
+ <attr name="android:shadowColor" />
+ </declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 58717c273..47bc5b568 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -25,13 +25,8 @@
<color name="focused_background">#80c6c5c5</color>
- <color name="workspace_icon_text_color">#FFF</color>
- <color name="workspace_edge_effect_color">#FFFFFFFF</color>
-
<color name="default_shadow_color_no_alpha">#FF000000</color>
- <color name="outline_color">#FFFFFFFF</color>
-
<color name="spring_loaded_panel_color">#40FFFFFF</color>
<color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
@@ -41,9 +36,6 @@
<color name="notification_icon_default_color">#757575</color> <!-- Gray 600 -->
<color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 -->
- <!-- System shortcuts -->
- <color name="system_shortcuts_icon_color">@android:color/tertiary_text_light</color>
-
- <color name="legacy_icon_background">#FFFFFF</color>
<color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
+ <color name="legacy_icon_background">#FFFFFF</color>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index e949d4b3b..ace1d7e5f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -13,6 +13,10 @@
easily override the app name without providing all translations -->
<string name="derived_app_name" translatable="false">@string/app_name</string>
+ <!-- String representing the intent for search on the apps market. To specify a query, add
+ q=<query> to the data to the intent -->
+ <string name="market_search_intent" translatable="false">market://search?c=apps</string>
+
<!-- Values for icon shape overrides. These should correspond to entries defined
in icon_shape_override_paths_names -->
<string-array name="icon_shape_override_paths_values">
@@ -76,6 +80,7 @@
<integer name="config_folderExpandDuration">120</integer>
<integer name="config_materialFolderExpandDuration">200</integer>
<integer name="config_materialFolderExpandStagger">60</integer>
+ <integer name="config_folderDelay">30</integer>
<!-- The distance at which the animation should take the max duration -->
<integer name="config_dropAnimMaxDist">800</integer>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index bd6466b46..b0f64a604 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -26,14 +26,17 @@
<dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
<dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen>
<dimen name="dynamic_grid_overview_bar_spacer_width">25dp</dimen>
- <dimen name="dynamic_grid_hotseat_height">88dp</dimen>
- <dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
- <dimen name="dynamic_grid_hotseat_gutter_width">24dp</dimen>
<dimen name="dynamic_grid_workspace_top_padding">12dp</dimen>
<dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
<!-- Minimum space between workspace and hotseat in spring loaded mode -->
<dimen name="dynamic_grid_min_spring_loaded_space">8dp</dimen>
+ <!-- Hotseat -->
+ <dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
+ <dimen name="dynamic_grid_hotseat_bottom_padding">0dp</dimen>
+ <dimen name="dynamic_grid_hotseat_height">80dp</dimen>
+ <dimen name="dynamic_grid_hotseat_land_gutter_width">24dp</dimen>
+
<!-- Drop target bar -->
<dimen name="dynamic_grid_drop_target_size">48dp</dimen>
<dimen name="vert_drop_target_vertical_gap">20dp</dimen>
@@ -45,11 +48,6 @@
<dimen name="resize_frame_background_padding">24dp</dimen>
<!-- Container -->
- <!-- Note: This needs to match the fixed insets for the search box. -->
- <dimen name="container_bounds_inset">8dp</dimen>
- <!-- Notes: container_bounds_inset - quantum_panel_outer_padding -->
- <dimen name="container_bounds_minus_quantum_panel_padding_inset">4dp</dimen>
-
<dimen name="container_fastscroll_thumb_min_width">5dp</dimen>
<dimen name="container_fastscroll_thumb_max_width">9dp</dimen>
<dimen name="container_fastscroll_popup_margin">18dp</dimen>
@@ -62,9 +60,6 @@
<dimen name="all_apps_button_scale_down">0dp</dimen>
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
<dimen name="all_apps_search_bar_height">60dp</dimen>
- <dimen name="all_apps_search_bar_icon_margin_right">4dp</dimen>
- <dimen name="all_apps_search_bar_icon_margin_top">1dp</dimen>
- <dimen name="all_apps_list_bottom_padding">8dp</dimen>
<dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
<dimen name="all_apps_empty_search_bg_top_offset">144dp</dimen>
<dimen name="all_apps_background_canvas_width">700dp</dimen>
@@ -143,6 +138,7 @@
<dimen name="blur_size_medium_outline">2dp</dimen>
<dimen name="blur_size_click_shadow">4dp</dimen>
<dimen name="click_shadow_high_shift">2dp</dimen>
+ <dimen name="drawable_shadow_size">4dp</dimen>
<!-- Pending widget -->
<dimen name="pending_widget_min_padding">8dp</dimen>
diff --git a/res/values/drawables.xml b/res/values/drawables.xml
new file mode 100644
index 000000000..fea17b153
--- /dev/null
+++ b/res/values/drawables.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+ <drawable name="ic_info_shadow">@drawable/ic_info_no_shadow</drawable>
+ <drawable name="ic_remove_shadow">@drawable/ic_remove_no_shadow</drawable>
+ <drawable name="ic_uninstall_shadow">@drawable/ic_uninstall_no_shadow</drawable>
+</resources> \ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8a46e839f..e2d9ff486 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -25,10 +25,22 @@
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:colorEdgeEffect">#FF757575</item>
+ <item name="android:keyboardLayout">@layout/all_apps_search_container</item>
</style>
<style name="LauncherTheme" parent="@style/BaseLauncherTheme"></style>
+ <!--
+ Theme overrides to element on homescreen, i.e., which are drawn on top on wallpaper.
+ Various foreground colors are overridden to be white so that they are properly visible on
+ various wallpapers
+ -->
+ <style name="HomeScreenElementTheme" parent="@style/LauncherTheme">
+ <item name="android:colorEdgeEffect">@android:color/white</item>
+ <item name="android:textColorPrimary">@android:color/white</item>
+ <item name="android:textColorSecondary">@android:color/white</item>
+ </style>
+
<!-- Theme for the widget container. Overridden on API 26. -->
<style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="android:colorEdgeEffect">?android:attr/textColorSecondaryInverse</item>
@@ -76,17 +88,31 @@
<!-- Icon displayed on the worksapce -->
<style name="BaseIcon.Workspace">
<item name="customShadows">true</item>
- <item name="android:textColor">@color/workspace_icon_text_color</item>
<item name="android:shadowRadius">2.0</item>
<item name="android:shadowColor">#B0000000</item>
</style>
+ <!-- Theme for the popup container -->
+ <style name="PopupContainer" parent="@style/LauncherTheme">
+ <!-- TODO: move hardcoded colors from colors.xml to this theme and use for popup items -->
+ </style>
+ <style name="IconOnlySystemShortcut">
+ <!-- The icons use this color, then are tinted -->
+ <item name="android:textColorPrimary">@android:color/white</item>
+ <item name="android:tint">?android:attr/textColorHint</item>
+ </style>
+ <style name="IconWithTextSystemShortcut">
+ <!-- The icons use this color, then are tinted -->
+ <item name="android:textColorPrimary">@android:color/white</item>
+ <item name="android:backgroundTint">?android:attr/textColorTertiary</item>
+ </style>
+
<!-- Drop targets -->
<style name="DropTargetButtonBase">
<item name="android:drawablePadding">7.5dp</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">16dp</item>
- <item name="android:textColor">@color/workspace_icon_text_color</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">@dimen/drop_target_text_size</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml
index 7e833a0ca..299e92ea1 100644
--- a/res/xml/backupscheme.xml
+++ b/res/xml/backupscheme.xml
@@ -3,5 +3,6 @@
<include domain="database" path="launcher.db" />
<include domain="sharedpref" path="com.android.launcher3.prefs.xml" />
+ <include domain="file" path="downgrade_schema.json" />
</full-backup-content> \ No newline at end of file
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 5b42cad96..d7f0180fa 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -18,10 +18,15 @@ package com.android.launcher3;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
+import android.os.Process;
import android.os.UserHandle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -69,7 +74,7 @@ public class AllAppsList {
if (!mAppFilter.shouldShowApp(info.componentName)) {
return;
}
- if (findActivity(data, info.componentName, info.user)) {
+ if (findAppInfo(info.componentName, info.user) != null) {
return;
}
mIconCache.getTitleAndIcon(info, activityInfo, true /* useLowResIcon */);
@@ -78,6 +83,25 @@ public class AllAppsList {
added.add(info);
}
+ public void addPromiseApp(Context context,
+ PackageInstallerCompat.PackageInstallInfo installInfo) {
+ ApplicationInfo applicationInfo = LauncherAppsCompat.getInstance(context)
+ .getApplicationInfo(installInfo.packageName, 0, Process.myUserHandle());
+ // only if not yet installed
+ if (applicationInfo == null) {
+ PromiseAppInfo info = new PromiseAppInfo(installInfo);
+ mIconCache.getTitleAndIcon(info, info.usingLowResIcon);
+ data.add(info);
+ added.add(info);
+ }
+ }
+
+ public void removePromiseApp(AppInfo appInfo) {
+ // the <em>removed</em> list is handled by the caller
+ // so not adding it here
+ data.remove(appInfo);
+ }
+
public void clear() {
data.clear();
// TODO: do we clear these too?
@@ -169,9 +193,7 @@ public class AllAppsList {
// Find enabled activities and add them to the adapter
// Also updates existing activities with new labels/icons
for (final LauncherActivityInfo info : matches) {
- AppInfo applicationInfo = findApplicationInfoLocked(
- info.getComponentName().getPackageName(), user,
- info.getComponentName().getClassName());
+ AppInfo applicationInfo = findAppInfo(info.getComponentName(), user);
if (applicationInfo == null) {
add(new AppInfo(context, info, user), info);
} else {
@@ -208,28 +230,14 @@ public class AllAppsList {
}
/**
- * Returns whether <em>apps</em> contains <em>component</em>.
- */
- private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
- UserHandle user) {
- final int N = apps.size();
- for (int i = 0; i < N; i++) {
- final AppInfo info = apps.get(i);
- if (info.user.equals(user) && info.componentName.equals(component)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Find an ApplicationInfo object for the given packageName and className.
+ * Find an AppInfo object for the given componentName
+ *
+ * @return the corresponding AppInfo or null
*/
- private AppInfo findApplicationInfoLocked(String packageName, UserHandle user,
- String className) {
+ private @Nullable AppInfo findAppInfo(@NonNull ComponentName componentName,
+ @NonNull UserHandle user) {
for (AppInfo info: data) {
- if (user.equals(info.user) && packageName.equals(info.componentName.getPackageName())
- && className.equals(info.componentName.getClassName())) {
+ if (componentName.equals(info.componentName) && user.equals(info.user)) {
return info;
}
}
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index c4086a89d..98eb208eb 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -393,7 +393,7 @@ public class AutoInstallsLayout {
return -1;
}
- mValues.put(Favorites.RESTORED, ShortcutInfo.FLAG_AUTOINTALL_ICON);
+ mValues.put(Favorites.RESTORED, ShortcutInfo.FLAG_AUTOINSTALL_ICON);
final Intent intent = new Intent(Intent.ACTION_MAIN, null)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setComponent(new ComponentName(packageName, className))
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 6fdf45450..1e6d89485 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -82,10 +82,6 @@ public abstract class BaseRecyclerView extends RecyclerView
}
}
- public void reset() {
- mScrollbar.reattachThumbToScroll();
- }
-
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -117,6 +113,7 @@ public abstract class BaseRecyclerView extends RecyclerView
* it is already showing).
*/
private boolean handleTouchEvent(MotionEvent ev) {
+ ev.offsetLocation(0, -getPaddingTop());
int action = ev.getAction();
int x = (int) ev.getX();
int y = (int) ev.getY();
@@ -140,6 +137,7 @@ public abstract class BaseRecyclerView extends RecyclerView
mScrollbar.handleTouchEvent(ev, mDownX, mDownY, mLastY);
break;
}
+ ev.offsetLocation(0, getPaddingTop());
return mScrollbar.isDraggingThumb();
}
@@ -166,7 +164,7 @@ public abstract class BaseRecyclerView extends RecyclerView
* Returns the height of the fast scroll bar
*/
protected int getScrollbarTrackHeight() {
- return getHeight();
+ return getHeight() - getPaddingTop() - getPaddingBottom();
}
/**
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
index 5feb42ea8..303974464 100644
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
+++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
@@ -136,6 +136,7 @@ public class BaseRecyclerViewFastScrollBar {
mTmpRect.set(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
mThumbOffsetY = y;
mTmpRect.union(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
+ mTmpRect.offset(0, mRv.getPaddingTop());
mRv.invalidate(mTmpRect);
}
@@ -148,8 +149,9 @@ public class BaseRecyclerViewFastScrollBar {
return;
}
int left = getDrawLeft();
+ int top = mRv.getPaddingTop();
// Invalidate the whole scroll bar area.
- mRv.invalidate(left, 0, left + mMaxWidth, mRv.getScrollbarTrackHeight());
+ mRv.invalidate(left, top, left + mMaxWidth, top + mRv.getScrollbarTrackHeight());
mWidth = width;
updateThumbPath();
@@ -265,6 +267,7 @@ public class BaseRecyclerViewFastScrollBar {
if (!mIsRtl) {
canvas.translate(mRv.getWidth(), 0);
}
+ canvas.translate(0, mRv.getPaddingTop());
// Draw the track
int thumbWidth = mIsRtl ? mWidth : -mWidth;
canvas.drawRect(0, 0, thumbWidth, mRv.getScrollbarTrackHeight(), mTrackPaint);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index cb40d3d5e..07236d6a0 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -43,7 +43,7 @@ import com.android.launcher3.IconCache.IconLoadRequest;
import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.badge.BadgeRenderer;
-import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.FolderIconPreviewVerifier;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.graphics.HolographicOutlineHelper;
import com.android.launcher3.graphics.IconPalette;
@@ -206,6 +206,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
// Verify high res immediately
verifyHighRes();
+ if (info instanceof PromiseAppInfo) {
+ PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
+ applyProgressLevel(promiseAppInfo.level);
+ }
applyBadgeState(info, false /* animate */);
}
@@ -547,27 +551,36 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
((info.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE) ?
info.getInstallProgress() : 0)) : 100;
- setContentDescription(progressLevel > 0 ?
- getContext().getString(R.string.app_downloading_title, info.title,
- NumberFormat.getPercentInstance().format(progressLevel * 0.01)) :
- getContext().getString(R.string.app_waiting_download_title, info.title));
+ PreloadIconDrawable preloadDrawable = applyProgressLevel(progressLevel);
+ if (preloadDrawable != null && promiseStateChanged) {
+ preloadDrawable.maybePerformFinishedAnimation();
+ }
+ }
+ }
+
+ public PreloadIconDrawable applyProgressLevel(int progressLevel) {
+ if (getTag() instanceof ItemInfoWithIcon) {
+ ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
+ setContentDescription(progressLevel > 0
+ ? getContext().getString(R.string.app_downloading_title, info.title,
+ NumberFormat.getPercentInstance().format(progressLevel * 0.01))
+ : getContext().getString(R.string.app_waiting_download_title, info.title));
if (mIcon != null) {
final PreloadIconDrawable preloadDrawable;
if (mIcon instanceof PreloadIconDrawable) {
preloadDrawable = (PreloadIconDrawable) mIcon;
+ preloadDrawable.setLevel(progressLevel);
} else {
preloadDrawable = DrawableFactory.get(getContext())
.newPendingIcon(info.iconBitmap, getContext());
+ preloadDrawable.setLevel(progressLevel);
setIcon(preloadDrawable);
}
-
- preloadDrawable.setLevel(progressLevel);
- if (promiseStateChanged) {
- preloadDrawable.maybePerformFinishedAnimation();
- }
+ return preloadDrawable;
}
}
+ return null;
}
public void applyBadgeState(ItemInfo itemInfo, boolean animate) {
@@ -627,7 +640,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
applyFromApplicationInfo((AppInfo) info);
} else if (info instanceof ShortcutInfo) {
applyFromShortcutInfo((ShortcutInfo) info);
- if ((info.rank < FolderIcon.NUM_ITEMS_IN_PREVIEW) && (info.container >= 0)) {
+ FolderIconPreviewVerifier verifier =
+ new FolderIconPreviewVerifier(mLauncher.getDeviceProfile().inv);
+ if (verifier.isItemInPreview(info.rank) && (info.container >= 0)) {
View folderIcon =
mLauncher.getWorkspace().getHomescreenIconByItemId(info.container);
if (folderIcon != null) {
@@ -667,6 +682,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
.isEmpty();
}
+ public int getIconSize() {
+ return mIconSize;
+ }
+
/**
* Interface to be implemented by the grand parent to allow click shadow effect.
*/
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 8179dad29..c0946a0e3 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -51,12 +51,13 @@ import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
import com.android.launcher3.accessibility.FolderAccessibilityHelper;
import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.anim.PropertyListBuilder;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.util.CellAndSpan;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.ParcelableSparseArray;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import java.lang.annotation.Retention;
@@ -235,7 +236,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
for (int i = 0; i < mDragOutlines.length; i++) {
mDragOutlines[i] = new Rect(-1, -1, -1, -1);
}
- mDragOutlinePaint.setColor(getResources().getColor(R.color.outline_color));
+ mDragOutlinePaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary));
// When dragging things around the home screens, we show a green outline of
// where the item will land. The outlines gradually fade out, leaving a trail
@@ -568,7 +569,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
try {
dispatchRestoreInstanceState(states);
} catch (IllegalArgumentException ex) {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw ex;
}
// Mismatched viewId / viewType preventing restore. Skip restore on production builds.
diff --git a/src/com/android/launcher3/DeferredHandler.java b/src/com/android/launcher3/DeferredHandler.java
deleted file mode 100644
index a43ab6723..000000000
--- a/src/com/android/launcher3/DeferredHandler.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.MessageQueue;
-
-import com.android.launcher3.util.Thunk;
-
-import java.util.LinkedList;
-
-/**
- * Queue of things to run on a looper thread. Items posted with {@link #post} will not
- * be actually enqued on the handler until after the last one has run, to keep from
- * starving the thread.
- *
- * This class is fifo.
- */
-public class DeferredHandler {
- @Thunk LinkedList<Runnable> mQueue = new LinkedList<>();
- private MessageQueue mMessageQueue = Looper.myQueue();
- private Impl mHandler = new Impl();
-
- @Thunk class Impl extends Handler implements MessageQueue.IdleHandler {
- public void handleMessage(Message msg) {
- Runnable r;
- synchronized (mQueue) {
- if (mQueue.size() == 0) {
- return;
- }
- r = mQueue.removeFirst();
- }
- r.run();
- synchronized (mQueue) {
- scheduleNextLocked();
- }
- }
-
- public boolean queueIdle() {
- handleMessage(null);
- return false;
- }
- }
-
- private class IdleRunnable implements Runnable {
- Runnable mRunnable;
-
- IdleRunnable(Runnable r) {
- mRunnable = r;
- }
-
- public void run() {
- mRunnable.run();
- }
- }
-
- public DeferredHandler() {
- }
-
- /** Schedule runnable to run after everything that's on the queue right now. */
- public void post(Runnable runnable) {
- synchronized (mQueue) {
- mQueue.add(runnable);
- if (mQueue.size() == 1) {
- scheduleNextLocked();
- }
- }
- }
-
- /** Schedule runnable to run when the queue goes idle. */
- public void postIdle(final Runnable runnable) {
- post(new IdleRunnable(runnable));
- }
-
- public void cancelAll() {
- synchronized (mQueue) {
- mQueue.clear();
- }
- }
-
- /** Runs all queued Runnables from the calling thread. */
- public void flush() {
- LinkedList<Runnable> queue = new LinkedList<>();
- synchronized (mQueue) {
- queue.addAll(mQueue);
- mQueue.clear();
- }
- for (Runnable r : queue) {
- r.run();
- }
- }
-
- void scheduleNextLocked() {
- if (mQueue.size() > 0) {
- Runnable peek = mQueue.getFirst();
- if (peek instanceof IdleRunnable) {
- mMessageQueue.addIdleHandler(mHandler);
- } else {
- mHandler.sendEmptyMessage(1);
- }
- }
- }
-}
-
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 9097ed23d..975675a6f 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -40,7 +40,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
// Get the hover color
mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
- setDrawable(R.drawable.ic_remove_launcher);
+ setDrawable(R.drawable.ic_remove_shadow);
}
@Override
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index e47031ae8..2d1ebf114 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -191,11 +191,14 @@ public class DeviceProfile {
dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
- hotseatBarHeightPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height);
+
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
- hotseatBarBottomPaddingPx = 0;
- hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_gutter_width);
+ hotseatBarBottomPaddingPx =
+ res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
+ hotseatBarHeightPx = hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx +
+ res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height);
+ hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_land_gutter_width);
// Determine sizes.
widthPx = width;
@@ -228,9 +231,6 @@ public class DeviceProfile {
profile.cellHeightPx = profile.iconSizePx + profile.iconDrawablePaddingPx
+ Utilities.calculateTextHeight(profile.iconTextSizePx);
- // The nav bar is black so we add bottom padding to visually center hotseat icons.
- profile.hotseatBarBottomPaddingPx = profile.hotseatBarTopPaddingPx;
-
// We use these scales to measure and layout the widgets using their full invariant profile
// sizes and then draw them scaled and centered to fit in their multi-window mode cellspans.
float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x;
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index b36734bab..fe7acda17 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -22,7 +22,7 @@ import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderPagedView;
import com.android.launcher3.util.FocusLogic;
@@ -93,7 +93,7 @@ public class FocusHelper {
}
if (!(v.getParent() instanceof ShortcutAndWidgetContainer)) {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new IllegalStateException("Parent of the focused item is not supported.");
} else {
return false;
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 47052a77e..ab82c988e 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -72,7 +72,9 @@ public class Hotseat extends FrameLayout
mBackgroundColor = ColorUtils.setAlphaComponent(
Themes.getAttrColor(context, android.R.attr.colorPrimary), 0);
mBackground = new ColorDrawable(mBackgroundColor);
- setBackground(mBackground);
+ if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ setBackground(mBackground);
+ }
}
public CellLayout getLayout() {
@@ -179,8 +181,12 @@ public class Hotseat extends FrameLayout
}
public void updateColor(ExtractedColors extractedColors, boolean animate) {
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ // not hotseat visible
+ return;
+ }
if (!mHasVerticalHotseat) {
- int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
+ int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX);
if (mBackgroundColorAnimator != null) {
mBackgroundColorAnimator.cancel();
}
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 0608fdd2e..f088d1176 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -42,12 +42,10 @@ public class InfoDropTarget extends UninstallDropTarget {
}
@Override
- protected void onFinishInflate() {
- super.onFinishInflate();
+ protected void setupUi() {
// Get the hover color
mHoverColor = Themes.getColorAccent(getContext());
-
- setDrawable(R.drawable.ic_info_launcher);
+ setDrawable(R.drawable.ic_info_shadow);
}
@Override
@@ -67,6 +65,11 @@ public class InfoDropTarget extends UninstallDropTarget {
public static boolean startDetailsActivityForInfo(ItemInfo info, Launcher launcher,
DropTargetResultCallback callback, Rect sourceBounds, Bundle opts) {
+ if (info instanceof PromiseAppInfo) {
+ PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
+ launcher.startActivity(promiseAppInfo.getMarketIntent());
+ return true;
+ }
boolean result = false;
ComponentName componentName = null;
if (info instanceof AppInfo) {
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
index 154641cab..be7649013 100644
--- a/src/com/android/launcher3/InsettableFrameLayout.java
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -9,9 +9,6 @@ import android.view.ViewDebug;
import android.view.ViewGroup;
import android.widget.FrameLayout;
-import com.android.launcher3.allapps.AllAppsContainerView;
-import com.android.launcher3.config.FeatureFlags;
-
public class InsettableFrameLayout extends FrameLayout implements
ViewGroup.OnHierarchyChangeListener, Insettable {
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 9e214d1ec..d22461535 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -28,7 +28,6 @@ import android.view.Display;
import android.view.WindowManager;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.util.Thunk;
import org.xmlpull.v1.XmlPullParser;
@@ -317,7 +316,7 @@ public class InvariantDeviceProfile {
}
public int getAllAppsButtonRank() {
- if (ProviderConfig.IS_DOGFOOD_BUILD && FeatureFlags.NO_ALL_APPS_ICON) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && FeatureFlags.NO_ALL_APPS_ICON) {
throw new IllegalAccessError("Accessing all apps rank when all-apps is disabled");
}
return numHotseatIcons / 2;
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 0779a3d20..11c5309f2 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -39,8 +39,10 @@ public class ItemInfo {
/**
* One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
* {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
- * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or
- * {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}.
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_DEEP_SHORTCUT}
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER},
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET} or
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_CUSTOM_APPWIDGET}.
*/
public int itemType;
@@ -53,7 +55,9 @@ public class ItemInfo {
public long container = NO_ID;
/**
- * Indicates the screen in which the shortcut appears.
+ * Indicates the screen in which the shortcut appears if the container types is
+ * {@link LauncherSettings.Favorites#CONTAINER_DESKTOP}. (i.e., ignore if the container type is
+ * {@link LauncherSettings.Favorites#CONTAINER_HOTSEAT})
*/
public long screenId = -1;
@@ -178,15 +182,12 @@ public class ItemInfo {
protected String dumpProperties() {
return "id=" + id
- + " type=" + itemType
- + " container=" + container
+ + " type=" + LauncherSettings.Favorites.itemTypeToString(itemType)
+ + " container=" + LauncherSettings.Favorites.containerToString((int)container)
+ " screen=" + screenId
- + " cellX=" + cellX
- + " cellY=" + cellY
- + " spanX=" + spanX
- + " spanY=" + spanY
- + " minSpanX=" + minSpanX
- + " minSpanY=" + minSpanY
+ + " cell(" + cellX + "," + cellY + ")"
+ + " span(" + spanX + "," + spanY + ")"
+ + " minSpan(" + minSpanX + "," + minSpanY + ")"
+ " rank=" + rank
+ " user=" + user
+ " title=" + title;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index eef578d8f..4be25bb17 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,7 +18,9 @@ package com.android.launcher3;
import android.Manifest;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@@ -65,6 +67,7 @@ import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.KeyboardShortcutGroup;
import android.view.KeyboardShortcutInfo;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
@@ -84,13 +87,11 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.allapps.DefaultAppSearchController;
import com.android.launcher3.anim.AnimationLayerSet;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PinItemRequestCompat;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
@@ -213,6 +214,8 @@ public class Launcher extends BaseActivity
private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@Thunk static int NEW_APPS_ANIMATION_DELAY = 500;
+ private final ExtractedColors mExtractedColors = new ExtractedColors();
+
@Thunk Workspace mWorkspace;
private View mLauncherView;
@Thunk DragLayer mDragLayer;
@@ -261,13 +264,14 @@ public class Launcher extends BaseActivity
private LauncherModel mModel;
private ModelWriter mModelWriter;
private IconCache mIconCache;
- private ExtractedColors mExtractedColors;
private LauncherAccessibilityDelegate mAccessibilityDelegate;
private Handler mHandler = new Handler();
private boolean mIsResumeFromActionScreenOff;
private boolean mHasFocus = false;
private boolean mAttached = false;
+ private ObjectAnimator mScrimAnimator;
+
private PopupDataProvider mPopupDataProvider;
private View.OnTouchListener mHapticFeedbackTouchListener;
@@ -393,11 +397,10 @@ public class Launcher extends BaseActivity
// LauncherModel load.
mPaused = false;
- mLauncherView = getLayoutInflater().inflate(R.layout.launcher, null);
+ mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null);
setupViews();
mDeviceProfile.layout(this, false /* notifyListeners */);
- mExtractedColors = new ExtractedColors();
loadExtractedColorsAndColorItems();
mPopupDataProvider = new PopupDataProvider(this);
@@ -466,6 +469,11 @@ public class Launcher extends BaseActivity
@Override
public void onExtractedColorsChanged() {
loadExtractedColorsAndColorItems();
+ mExtractedColors.notifyChange();
+ }
+
+ public ExtractedColors getExtractedColors() {
+ return mExtractedColors;
}
@Override
@@ -481,9 +489,9 @@ public class Launcher extends BaseActivity
mExtractedColors.load(this);
mHotseat.updateColor(mExtractedColors, !mPaused);
mWorkspace.getPageIndicator().updateColor(mExtractedColors);
- boolean lightStatusBar = (FeatureFlags.LIGHT_STATUS_BAR
- && mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX,
- ExtractedColors.DEFAULT_DARK) == ExtractedColors.DEFAULT_LIGHT);
+ boolean lightStatusBar = (FeatureFlags.LIGHT_STATUS_BAR &&
+ mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX) ==
+ ExtractedColors.DEFAULT_LIGHT);
// 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.
@@ -550,47 +558,6 @@ public class Launcher extends BaseActivity
public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
mLauncherCallbacks = callbacks;
- mLauncherCallbacks.setLauncherSearchCallback(new Launcher.LauncherSearchCallbacks() {
- private boolean mWorkspaceImportanceStored = false;
- private boolean mHotseatImportanceStored = false;
- private int mWorkspaceImportanceForAccessibility =
- View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
- private int mHotseatImportanceForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
-
- @Override
- public void onSearchOverlayOpened() {
- if (mWorkspaceImportanceStored || mHotseatImportanceStored) {
- return;
- }
- // The underlying workspace and hotseat are temporarily suppressed by the search
- // overlay. So they shouldn't be accessible.
- if (mWorkspace != null) {
- mWorkspaceImportanceForAccessibility =
- mWorkspace.getImportantForAccessibility();
- mWorkspace.setImportantForAccessibility(
- View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- mWorkspaceImportanceStored = true;
- }
- if (mHotseat != null) {
- mHotseatImportanceForAccessibility = mHotseat.getImportantForAccessibility();
- mHotseat.setImportantForAccessibility(
- View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- mHotseatImportanceStored = true;
- }
- }
-
- @Override
- public void onSearchOverlayClosed() {
- if (mWorkspaceImportanceStored && mWorkspace != null) {
- mWorkspace.setImportantForAccessibility(mWorkspaceImportanceForAccessibility);
- }
- if (mHotseatImportanceStored && mHotseat != null) {
- mHotseat.setImportantForAccessibility(mHotseatImportanceForAccessibility);
- }
- mWorkspaceImportanceStored = false;
- mHotseatImportanceStored = false;
- }
- });
return true;
}
@@ -952,6 +919,24 @@ public class Launcher extends BaseActivity
if (!isWorkspaceLoading()) {
NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
}
+
+ if (mIsResumeFromActionScreenOff && mDragLayer.getBackground() != null) {
+ if (mScrimAnimator != null) {
+ mScrimAnimator.cancel();
+ }
+ mDragLayer.getBackground().setAlpha(0);
+ mScrimAnimator = ObjectAnimator.ofInt(mDragLayer.getBackground(),
+ LauncherAnimUtils.DRAWABLE_ALPHA, 0, 255);
+ mScrimAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mScrimAnimator = null;
+ }
+ });
+ mScrimAnimator.setDuration(600);
+ mScrimAnimator.setStartDelay(getWindow().getTransitionBackgroundFadeDuration());
+ mScrimAnimator.start();
+ }
}
@Override
@@ -1130,18 +1115,6 @@ public class Launcher extends BaseActivity
public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks);
}
- public interface LauncherSearchCallbacks {
- /**
- * Called when the search overlay is shown.
- */
- public void onSearchOverlayOpened();
-
- /**
- * Called when the search overlay is dismissed.
- */
- public void onSearchOverlayClosed();
- }
-
public interface LauncherOverlayCallbacks {
public void onScrollChanged(float progress);
}
@@ -1334,11 +1307,6 @@ public class Launcher extends BaseActivity
// Setup Apps and Widgets
mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);
- if (mLauncherCallbacks != null && mLauncherCallbacks.getAllAppsSearchBarController() != null) {
- mAppsView.setSearchBarController(mLauncherCallbacks.getAllAppsSearchBarController());
- } else {
- mAppsView.setSearchBarController(new DefaultAppSearchController());
- }
// Setup the drag controller (drop targets have to be added in reverse order in priority)
mDragController.setMoveTarget(mWorkspace);
@@ -1429,8 +1397,8 @@ public class Launcher extends BaseActivity
* @return A View inflated from layoutResId.
*/
public View createShortcut(ViewGroup parent, ShortcutInfo info) {
- BubbleTextView favorite = (BubbleTextView) getLayoutInflater().inflate(R.layout.app_icon,
- parent, false);
+ BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.app_icon, parent, false);
favorite.applyFromShortcutInfo(info);
favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
favorite.setOnClickListener(this);
@@ -1767,7 +1735,7 @@ public class Launcher extends BaseActivity
// Reset the apps view
if (!alreadyOnHome && mAppsView != null) {
- mAppsView.scrollToTop();
+ mAppsView.reset();
}
// Reset the widgets view
@@ -2469,7 +2437,13 @@ public class Launcher extends BaseActivity
private void startAppShortcutOrInfoActivity(View v) {
ItemInfo item = (ItemInfo) v.getTag();
- Intent intent = item.getIntent();
+ Intent intent;
+ if (item instanceof PromiseAppInfo) {
+ PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
+ intent = promiseAppInfo.getMarketIntent();
+ } else {
+ intent = item.getIntent();
+ }
if (intent == null) {
throw new IllegalArgumentException("Input must have a valid intent");
}
@@ -3397,7 +3371,7 @@ public class Launcher extends BaseActivity
Object tag = v.getTag();
String desc = "Collision while binding workspace item: " + item
+ ". Collides with " + tag;
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw (new RuntimeException(desc));
} else {
Log.d(TAG, desc);
@@ -3600,6 +3574,9 @@ public class Launcher extends BaseActivity
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();
info.restoreStatus = finalRestoreFlag;
+ if (info.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
+ info.pendingItemInfo = null;
+ }
mWorkspace.reinflateWidgetsIfNecessary();
getModelWriter().updateItemInDatabase(info);
@@ -3775,6 +3752,22 @@ public class Launcher extends BaseActivity
}
@Override
+ public void bindPromiseAppProgressUpdated(final PromiseAppInfo app) {
+ Runnable r = new Runnable() {
+ public void run() {
+ bindPromiseAppProgressUpdated(app);
+ }
+ };
+ if (waitUntilResume(r)) {
+ return;
+ }
+
+ if (mAppsView != null) {
+ mAppsView.updatePromiseAppProgress(app);
+ }
+ }
+
+ @Override
public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
Runnable r = new Runnable() {
public void run() {
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index aa7f5ee5f..cfb9b570b 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -21,11 +21,10 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
+import android.graphics.drawable.Drawable;
import android.util.Property;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import android.widget.ViewAnimator;
import java.util.HashSet;
import java.util.WeakHashMap;
@@ -130,4 +129,16 @@ public class LauncherAnimUtils {
return anim;
}
+ public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
+ new Property<Drawable, Integer>(Integer.TYPE, "drawableAlpha") {
+ @Override
+ public Integer get(Drawable drawable) {
+ return drawable.getAlpha();
+ }
+
+ @Override
+ public void set(Drawable drawable, Integer alpha) {
+ drawable.setAlpha(alpha);
+ }
+ };
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 180c202fa..27ccabea9 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -26,7 +26,7 @@ import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.Preconditions;
@@ -37,7 +37,7 @@ import java.util.concurrent.ExecutionException;
public class LauncherAppState {
- public static final boolean PROFILE_STARTUP = ProviderConfig.IS_DOGFOOD_BUILD;
+ public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD;
// We do not need any synchronization for this variable as its only written on UI thread.
private static LauncherAppState INSTANCE;
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 1e0f28546..6f23e56b3 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -21,6 +21,7 @@ import android.content.ComponentName;
import android.content.Intent;
import android.os.Process;
+import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.ContentWriter;
/**
@@ -95,6 +96,11 @@ public class LauncherAppWidgetInfo extends ItemInfo {
*/
public Intent bindOptions;
+ /**
+ * Nonnull for pending widgets. We use this to get the icon and title for the widget.
+ */
+ public PackageItemInfo pendingItemInfo;
+
private boolean mHasNotifiedInitialWidgetSizeChanged;
public LauncherAppWidgetInfo(int appWidgetId, ComponentName providerName) {
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
index 2bac11f97..d66b14c7d 100644
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -17,13 +17,10 @@
package com.android.launcher3;
import android.content.Intent;
-import android.graphics.Rect;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
-import com.android.launcher3.allapps.AllAppsSearchBarController;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.util.ComponentKey;
import java.io.FileDescriptor;
@@ -44,69 +41,60 @@ public interface LauncherCallbacks {
* Activity life-cycle methods. These methods are triggered after
* the code in the corresponding Launcher method is executed.
*/
- public void preOnCreate();
- public void onCreate(Bundle savedInstanceState);
- public void preOnResume();
- public void onResume();
- public void onStart();
- public void onStop();
- public void onPause();
- public void onDestroy();
- public void onSaveInstanceState(Bundle outState);
- public void onPostCreate(Bundle savedInstanceState);
- public void onNewIntent(Intent intent);
- public void onActivityResult(int requestCode, int resultCode, Intent data);
- public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ void preOnCreate();
+ void onCreate(Bundle savedInstanceState);
+ void preOnResume();
+ void onResume();
+ void onStart();
+ void onStop();
+ void onPause();
+ void onDestroy();
+ void onSaveInstanceState(Bundle outState);
+ void onPostCreate(Bundle savedInstanceState);
+ void onNewIntent(Intent intent);
+ void onActivityResult(int requestCode, int resultCode, Intent data);
+ void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults);
- public void onWindowFocusChanged(boolean hasFocus);
- public void onAttachedToWindow();
- public void onDetachedFromWindow();
- public boolean onPrepareOptionsMenu(Menu menu);
- public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
- public void onHomeIntent();
- public boolean handleBackPressed();
- public void onTrimMemory(int level);
+ void onWindowFocusChanged(boolean hasFocus);
+ void onAttachedToWindow();
+ void onDetachedFromWindow();
+ boolean onPrepareOptionsMenu(Menu menu);
+ void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
+ void onHomeIntent();
+ boolean handleBackPressed();
+ void onTrimMemory(int level);
/*
* Extension points for providing custom behavior on certain user interactions.
*/
- public void onLauncherProviderChange();
- public void finishBindingItems(final boolean upgradePath);
- public void bindAllApplications(ArrayList<AppInfo> apps);
- public void onInteractionBegin();
- public void onInteractionEnd();
+ void onLauncherProviderChange();
+ void finishBindingItems(final boolean upgradePath);
+ void bindAllApplications(ArrayList<AppInfo> apps);
+ void onInteractionBegin();
+ void onInteractionEnd();
@Deprecated
- public void onWorkspaceLockedChanged();
+ void onWorkspaceLockedChanged();
/**
* Starts a search with {@param initialQuery}. Return false if search was not started.
*/
- public boolean startSearch(
+ boolean startSearch(
String initialQuery, boolean selectInitialQuery, Bundle appSearchData);
- public boolean hasCustomContentToLeft();
- public void populateCustomContentContainer();
- public View getQsbBar();
- public Bundle getAdditionalSearchWidgetOptions();
+ boolean hasCustomContentToLeft();
+ void populateCustomContentContainer();
+ View getQsbBar();
+ Bundle getAdditionalSearchWidgetOptions();
/*
* Extensions points for adding / replacing some other aspects of the Launcher experience.
*/
- public boolean shouldMoveToDefaultScreenOnHomeIntent();
- public boolean hasSettings();
- public AllAppsSearchBarController getAllAppsSearchBarController();
- public List<ComponentKey> getPredictedApps();
- public static final int SEARCH_BAR_HEIGHT_NORMAL = 0, SEARCH_BAR_HEIGHT_TALL = 1;
+ boolean shouldMoveToDefaultScreenOnHomeIntent();
+ boolean hasSettings();
+ List<ComponentKey> getPredictedApps();
+ int SEARCH_BAR_HEIGHT_NORMAL = 0, SEARCH_BAR_HEIGHT_TALL = 1;
/** Must return one of {@link #SEARCH_BAR_HEIGHT_NORMAL} or {@link #SEARCH_BAR_HEIGHT_TALL} */
- public int getSearchBarHeight();
+ int getSearchBarHeight();
- /**
- * Sets the callbacks to allow reacting the actions of search overlays of the launcher.
- *
- * @param callbacks A set of callbacks to the Launcher, is actually a LauncherSearchCallback,
- * but for implementation purposes is passed around as an object.
- */
- public void setLauncherSearchCallback(Object callbacks);
-
- public boolean shouldShowDiscoveryBounce();
+ boolean shouldShowDiscoveryBounce();
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index e68e637c5..ca9f3120d 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageInstaller;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
@@ -45,10 +46,11 @@ import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.FolderIconPreviewVerifier;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.AddWorkspaceItemsTask;
@@ -72,6 +74,7 @@ import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.ManagedProfileHeuristic;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
@@ -111,9 +114,9 @@ public class LauncherModel extends BroadcastReceiver
private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
private static final long INVALID_SCREEN_ID = -1L;
+ private final MainThreadExecutor mUiExecutor = new MainThreadExecutor();
@Thunk final LauncherAppState mApp;
@Thunk final Object mLock = new Object();
- @Thunk DeferredHandler mHandler = new DeferredHandler();
@Thunk LoaderTask mLoaderTask;
@Thunk boolean mIsLoaderTaskRunning;
@Thunk boolean mHasLoaderCompletedOnce;
@@ -193,6 +196,7 @@ public class LauncherModel extends BroadcastReceiver
ArrayList<ItemInfo> addAnimated,
ArrayList<AppInfo> addedApps);
public void bindAppsUpdated(ArrayList<AppInfo> apps);
+ public void bindPromiseAppProgressUpdated(PromiseAppInfo app);
public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated,
ArrayList<ShortcutInfo> removed, UserHandle user);
public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
@@ -219,17 +223,6 @@ public class LauncherModel extends BroadcastReceiver
mUserManager = UserManagerCompat.getInstance(context);
}
- /** Runs the specified runnable immediately if called from the main thread, otherwise it is
- * posted on the main thread handler. */
- private void runOnMainThread(Runnable r) {
- if (sWorkerThread.getThreadId() == Process.myTid()) {
- // If we are on the worker thread, post onto the main handler
- mHandler.post(r);
- } else {
- r.run();
- }
- }
-
/** Runs the specified runnable immediately if called from the worker thread, otherwise it is
* posted on the worker thread handler. */
private static void runOnWorkerThread(Runnable r) {
@@ -379,8 +372,6 @@ public class LauncherModel extends BroadcastReceiver
public void initialize(Callbacks callbacks) {
synchronized (mLock) {
Preconditions.assertUIThread();
- // Remove any queued UI runnables
- mHandler.cancelAll();
mCallbacks = new WeakReference<>(callbacks);
}
}
@@ -544,11 +535,11 @@ public class LauncherModel extends BroadcastReceiver
if (mCallbacks != null && mCallbacks.get() != null) {
final Callbacks oldCallbacks = mCallbacks.get();
// Clear any pending bind-runnables from the synchronized load process.
- runOnMainThread(new Runnable() {
- public void run() {
- oldCallbacks.clearPendingBinds();
- }
- });
+ mUiExecutor.execute(new Runnable() {
+ public void run() {
+ oldCallbacks.clearPendingBinds();
+ }
+ });
// If there is already one running, tell it to stop.
stopLoaderLocked();
@@ -586,6 +577,25 @@ public class LauncherModel extends BroadcastReceiver
screensUri, null, null, null, LauncherSettings.WorkspaceScreens.SCREEN_RANK));
}
+ public void onInstallSessionCreated(final PackageInstallInfo sessionInfo) {
+ enqueueModelUpdateTask(new ExtendedModelTask() {
+ @Override
+ public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
+ apps.addPromiseApp(app.getContext(), sessionInfo);
+ if (!apps.added.isEmpty()) {
+ final ArrayList<AppInfo> arrayList = new ArrayList<>(apps.added);
+ apps.added.clear();
+ scheduleCallbackTask(new CallbackTask() {
+ @Override
+ public void execute(Callbacks callbacks) {
+ callbacks.bindAppsAdded(null, null, null, arrayList);
+ }
+ });
+ }
+ }
+ });
+ }
+
/**
* Runnable for the thread that loads the contents of the launcher:
* - workspace icons
@@ -599,7 +609,6 @@ public class LauncherModel extends BroadcastReceiver
@Thunk boolean mIsLoadingAndBindingWorkspace;
private boolean mStopped;
- @Thunk boolean mLoadAndBindStepFinished;
LoaderTask(Context context, int pageToBindFirst) {
mContext = context;
@@ -611,34 +620,10 @@ public class LauncherModel extends BroadcastReceiver
// This way we don't start loading all apps until the workspace has settled
// down.
synchronized (LoaderTask.this) {
- final long workspaceWaitTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-
- mHandler.postIdle(new Runnable() {
- public void run() {
- synchronized (LoaderTask.this) {
- mLoadAndBindStepFinished = true;
- if (DEBUG_LOADERS) {
- Log.d(TAG, "done with previous binding step");
- }
- LoaderTask.this.notify();
- }
- }
- });
-
- while (!mStopped && !mLoadAndBindStepFinished) {
- try {
- // Just in case mFlushingWorkerThread changes but we aren't woken up,
- // wait no longer than 1sec at a time
- this.wait(1000);
- } catch (InterruptedException ex) {
- // Ignore
- }
- }
- if (DEBUG_LOADERS) {
- Log.d(TAG, "waited "
- + (SystemClock.uptimeMillis()-workspaceWaitTime)
- + "ms for previous step to finish binding");
- }
+ LooperIdleLock idleLock = new LooperIdleLock(this, Looper.getMainLooper());
+ // Just in case mFlushingWorkerThread changes but we aren't woken up,
+ // wait no longer than 1sec at a time
+ while (!mStopped && idleLock.awaitLocked(1000));
}
}
@@ -661,15 +646,6 @@ public class LauncherModel extends BroadcastReceiver
}
}
- // XXX: Throw an exception if we are already loading (since we touch the worker thread
- // data structures, we can't allow any other thread to touch that data, but because
- // this call is synchronous, we can get away with not locking).
-
- // The LauncherModel is static in the LauncherAppState and mHandler may have queued
- // operations from the previous activity. We need to ensure that all queued operations
- // are executed before any synchronous binding work is done.
- mHandler.flush();
-
// Divide the set of loaded items into those that we are binding synchronously, and
// everything else that is to be bound normally (asynchronously).
bindWorkspace(synchronousBindPage);
@@ -697,6 +673,7 @@ public class LauncherModel extends BroadcastReceiver
}
try {
+ long now = 0;
if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
// Set to false in bindWorkspace()
mIsLoadingAndBindingWorkspace = true;
@@ -707,8 +684,12 @@ public class LauncherModel extends BroadcastReceiver
bindWorkspace(mPageToBindFirst);
// Take a break
- if (DEBUG_LOADERS) Log.d(TAG, "step 1 completed, wait for idle");
+ if (DEBUG_LOADERS) {
+ Log.d(TAG, "step 1 completed, wait for idle");
+ now = SystemClock.uptimeMillis();
+ }
waitForIdle();
+ if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
verifyNotStopped();
// second step
@@ -720,8 +701,12 @@ public class LauncherModel extends BroadcastReceiver
updateIconCache();
// Take a break
- if (DEBUG_LOADERS) Log.d(TAG, "step 2 completed, wait for idle");
+ if (DEBUG_LOADERS) {
+ Log.d(TAG, "step 2 completed, wait for idle");
+ now = SystemClock.uptimeMillis();
+ }
waitForIdle();
+ if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
verifyNotStopped();
// third step
@@ -900,6 +885,8 @@ public class LauncherModel extends BroadcastReceiver
Intent intent;
String targetPkg;
+ FolderIconPreviewVerifier verifier =
+ new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
while (!mStopped && c.moveToNext()) {
try {
if (c.user == null) {
@@ -954,7 +941,7 @@ public class LauncherModel extends BroadcastReceiver
// no special handling necessary for this item
c.markRestored();
} else {
- if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+ if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
// We allow auto install apps to have their intent
// updated after an install.
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
@@ -1024,7 +1011,7 @@ public class LauncherModel extends BroadcastReceiver
}
boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() &&
- c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
+ !verifier.isItemInPreview(c.getInt(rankIndex));
if (c.restoreFlag != 0) {
// Already verified above that user is same as default user
@@ -1230,6 +1217,16 @@ public class LauncherModel extends BroadcastReceiver
.commit();
}
}
+
+ if (appWidgetInfo.restoreStatus !=
+ LauncherAppWidgetInfo.RESTORE_COMPLETED) {
+ String pkg = appWidgetInfo.providerName.getPackageName();
+ appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg);
+ appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
+ mIconCache.getTitleAndIconForApp(
+ appWidgetInfo.pendingItemInfo, false);
+ }
+
c.checkAndAddItem(appWidgetInfo, sBgDataModel);
}
break;
@@ -1278,17 +1275,23 @@ public class LauncherModel extends BroadcastReceiver
}
}
- // Sort all the folder items and make sure the first 3 items are high resolution.
+ FolderIconPreviewVerifier verifier =
+ new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
+ // Sort the folder items and make sure all items in the preview are high resolution.
for (FolderInfo folder : sBgDataModel.folders) {
Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
- int pos = 0;
+ verifier.setFolderInfo(folder);
+
+ int numItemsInPreview = 0;
for (ShortcutInfo info : folder.contents) {
- if (info.usingLowResIcon &&
- info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+ if (info.usingLowResIcon
+ && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+ && verifier.isItemInPreview(info.rank)) {
mIconCache.getTitleAndIcon(info, false);
+ numItemsInPreview++;
}
- pos ++;
- if (pos >= FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+
+ if (numItemsInPreview >= FolderIcon.NUM_ITEMS_IN_PREVIEW) {
break;
}
}
@@ -1413,7 +1416,7 @@ public class LauncherModel extends BroadcastReceiver
return Utilities.longCompare(lhs.screenId, rhs.screenId);
}
default:
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new RuntimeException("Unexpected container type when " +
"sorting workspace items.");
}
@@ -1438,7 +1441,7 @@ public class LauncherModel extends BroadcastReceiver
}
}
};
- runOnMainThread(r);
+ mUiExecutor.execute(r);
}
private void bindWorkspaceItems(final Callbacks oldCallbacks,
@@ -1544,11 +1547,11 @@ public class LauncherModel extends BroadcastReceiver
}
}
};
- runOnMainThread(r);
+ mUiExecutor.execute(r);
bindWorkspaceScreens(oldCallbacks, orderedScreenIds);
- Executor mainExecutor = new DeferredMainThreadExecutor();
+ Executor mainExecutor = mUiExecutor;
// Load items on the current page.
bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, mainExecutor);
@@ -1558,7 +1561,7 @@ public class LauncherModel extends BroadcastReceiver
// This ensures that the first screen is immediately visible (eg. during rotation)
// In case of !validFirstPage, bind all pages one after other.
final Executor deferredExecutor =
- validFirstPage ? new ViewOnDrawExecutor(mHandler) : mainExecutor;
+ validFirstPage ? new ViewOnDrawExecutor(mUiExecutor) : mainExecutor;
mainExecutor.execute(new Runnable() {
@Override
@@ -1618,7 +1621,7 @@ public class LauncherModel extends BroadcastReceiver
}
}
};
- runOnMainThread(r);
+ mUiExecutor.execute(r);
}
}
@@ -1668,7 +1671,7 @@ public class LauncherModel extends BroadcastReceiver
}
}
};
- runOnMainThread(r);
+ mUiExecutor.execute(r);
}
private void loadAllApps() {
@@ -1716,29 +1719,40 @@ public class LauncherModel extends BroadcastReceiver
heuristic.processUserApps(apps);
}
};
- runOnMainThread(new Runnable() {
+ mUiExecutor.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ // Check isLoadingWorkspace on the UI thread, as it is updated on
+ // the UI thread.
+ if (mIsLoadingAndBindingWorkspace) {
+ synchronized (mBindCompleteRunnables) {
+ mBindCompleteRunnables.add(r);
+ }
+ } else {
+ runOnWorkerThread(r);
+ }
+ }
+ });
+ }
+ }
- @Override
- public void run() {
- // Check isLoadingWorkspace on the UI thread, as it is updated on
- // the UI thread.
- if (mIsLoadingAndBindingWorkspace) {
- synchronized (mBindCompleteRunnables) {
- mBindCompleteRunnables.add(r);
- }
- } else {
- runOnWorkerThread(r);
- }
- }
- });
+ if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
+ // get all active sessions and add them to the all apps list
+ PackageInstallerCompat installer = PackageInstallerCompat.getInstance(mContext);
+ for (PackageInstaller.SessionInfo info : installer.getAllVerifiedSessions()) {
+ mBgAllAppsList.addPromiseApp(mContext,
+ PackageInstallInfo.fromInstallingState(info));
}
}
+
// Huh? Shouldn't this be inside the Runnable below?
final ArrayList<AppInfo> added = mBgAllAppsList.added;
mBgAllAppsList.added = new ArrayList<AppInfo>();
+
// Post callback on main thread
- mHandler.post(new Runnable() {
+ mUiExecutor.execute(new Runnable() {
public void run() {
final long bindTime = SystemClock.uptimeMillis();
@@ -1792,7 +1806,7 @@ public class LauncherModel extends BroadcastReceiver
}
}
};
- runOnMainThread(r);
+ mUiExecutor.execute(r);
}
/**
@@ -1843,12 +1857,12 @@ public class LauncherModel extends BroadcastReceiver
public static abstract class BaseModelUpdateTask implements Runnable {
private LauncherModel mModel;
- private DeferredHandler mUiHandler;
+ private Executor mUiExecutor;
/* package private */
void init(LauncherModel model) {
mModel = model;
- mUiHandler = mModel.mHandler;
+ mUiExecutor = mModel.mUiExecutor;
}
@Override
@@ -1871,7 +1885,7 @@ public class LauncherModel extends BroadcastReceiver
*/
public final void scheduleCallbackTask(final CallbackTask task) {
final Callbacks callbacks = mModel.getCallback();
- mUiHandler.post(new Runnable() {
+ mUiExecutor.execute(new Runnable() {
public void run() {
Callbacks cb = mModel.getCallback();
if (callbacks == cb && cb != null) {
@@ -1916,7 +1930,7 @@ public class LauncherModel extends BroadcastReceiver
private void bindWidgetsModel(final Callbacks callbacks) {
final MultiHashMap<PackageItemInfo, WidgetItem> widgets
= mBgWidgetsModel.getWidgetsMap().clone();
- mHandler.post(new Runnable() {
+ mUiExecutor.execute(new Runnable() {
@Override
public void run() {
Callbacks cb = getCallback();
@@ -1974,14 +1988,6 @@ public class LauncherModel extends BroadcastReceiver
}
}
- @Thunk class DeferredMainThreadExecutor implements Executor {
-
- @Override
- public void execute(Runnable command) {
- runOnMainThread(command);
- }
- }
-
/**
* @return the looper for the worker thread which can be used to start background tasks.
*/
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 3150d5b0e..c84a4312d 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -53,17 +53,19 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherSettings.WorkspaceScreens;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.graphics.IconShapeOverride;
import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.model.DbDowngradeHelper;
import com.android.launcher3.provider.LauncherDbUtils;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.util.ManagedProfileHeuristic;
import com.android.launcher3.util.NoLocaleSqliteContext;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Thunk;
+import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.reflect.Method;
@@ -71,25 +73,20 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
public class LauncherProvider extends ContentProvider {
private static final String TAG = "LauncherProvider";
private static final boolean LOGD = false;
+ private static final String DOWNGRADE_SCHEMA_FILE = "downgrade_schema.json";
+
/**
* Represents the schema of the database. Changes in scheme need not be backwards compatible.
*/
- private static final int SCHEMA_VERSION = 27;
- /**
- * Represents the actual data. It could include additional validations and normalizations added
- * overtime. These must be backwards compatible, else we risk breaking old devices during
- * restore or binary version downgrade.
- */
- private static final int DATA_VERSION = 3;
-
- private static final String PREF_KEY_DATA_VERISON = "provider_data_version";
+ public static final int SCHEMA_VERSION = 27;
- public static final String AUTHORITY = ProviderConfig.AUTHORITY;
+ public static final String AUTHORITY = (BuildConfig.APPLICATION_ID + ".settings").intern();
static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
@@ -114,7 +111,7 @@ public class LauncherProvider extends ContentProvider {
@Override
public boolean onCreate() {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
Log.d(TAG, "Launcher process started");
}
mListenerHandler = new Handler(mListenerWrapper);
@@ -305,8 +302,7 @@ public class LauncherProvider extends ContentProvider {
SqlArguments args = new SqlArguments(uri);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
int numValues = values.length;
for (int i = 0; i < numValues; i++) {
addModifiedTime(values[i]);
@@ -314,9 +310,7 @@ public class LauncherProvider extends ContentProvider {
return 0;
}
}
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
+ t.commit();
}
notifyListeners();
@@ -328,15 +322,11 @@ public class LauncherProvider extends ContentProvider {
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
createDbIfNotExists();
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(mOpenHelper.getWritableDatabase())) {
ContentProviderResult[] result = super.applyBatch(operations);
- db.setTransactionSuccessful();
+ t.commit();
reloadLauncherIfExternal();
return result;
- } finally {
- db.endTransaction();
}
}
@@ -442,31 +432,26 @@ public class LauncherProvider extends ContentProvider {
private ArrayList<Long> deleteEmptyFolders() {
ArrayList<Long> folderIds = new ArrayList<>();
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Select folders whose id do not match any container value.
String selection = LauncherSettings.Favorites.ITEM_TYPE + " = "
+ LauncherSettings.Favorites.ITEM_TYPE_FOLDER + " AND "
+ LauncherSettings.Favorites._ID + " NOT IN (SELECT " +
LauncherSettings.Favorites.CONTAINER + " FROM "
+ Favorites.TABLE_NAME + ")";
- Cursor c = db.query(Favorites.TABLE_NAME,
+ try (Cursor c = db.query(Favorites.TABLE_NAME,
new String[] {LauncherSettings.Favorites._ID},
- selection, null, null, null, null);
- while (c.moveToNext()) {
- folderIds.add(c.getLong(0));
+ selection, null, null, null, null)) {
+ LauncherDbUtils.iterateCursor(c, 0, folderIds);
}
- c.close();
if (!folderIds.isEmpty()) {
db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
LauncherSettings.Favorites._ID, folderIds), null);
}
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
folderIds.clear();
- } finally {
- db.endTransaction();
}
return folderIds;
}
@@ -714,50 +699,30 @@ public class LauncherProvider extends ContentProvider {
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
- SharedPreferences prefs = mContext
- .getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0);
- int oldVersion = prefs.getInt(PREF_KEY_DATA_VERISON, 0);
- if (oldVersion != DATA_VERSION) {
- // Only run the data upgrade path for an existing db.
- if (!Utilities.getPrefs(mContext).getBoolean(EMPTY_DATABASE_CREATED, false)) {
- db.beginTransaction();
- try {
- onDataUpgrade(db, oldVersion);
- db.setTransactionSuccessful();
- } catch (Exception e) {
- Log.d(TAG, "Error updating data version, ignoring", e);
- return;
- } finally {
- db.endTransaction();
- }
- }
- prefs.edit().putInt(PREF_KEY_DATA_VERISON, DATA_VERSION).apply();
+
+ File schemaFile = mContext.getFileStreamPath(DOWNGRADE_SCHEMA_FILE);
+ if (!schemaFile.exists()) {
+ handleOneTimeDataUpgrade(db);
}
+ DbDowngradeHelper.updateSchemaFile(schemaFile, SCHEMA_VERSION, mContext,
+ R.raw.downgrade_schema);
}
/**
- * Called when the data is updated as part of app update. It can be called multiple times
- * with old version, even though it had been run before. The changes made here must be
- * backwards compatible, else we risk breaking old devices during restore or binary
- * version downgrade.
+ * One-time data updated before support of onDowngrade was added. This update is backwards
+ * compatible and can safely be run multiple times.
+ * Note: No new logic should be added here after release, as the new logic might not get
+ * executed on an existing device.
+ * TODO: Move this to db upgrade path, once the downgrade path is released.
*/
- protected void onDataUpgrade(SQLiteDatabase db, int oldVersion) {
- switch (oldVersion) {
- case 0:
- case 1: {
- // Remove "profile extra"
- 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);
- }
- }
- case 2:
- case 3:
- // data updated
- return;
+ protected void handleOneTimeDataUpgrade(SQLiteDatabase db) {
+ // Remove "profile extra"
+ 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);
}
}
@@ -774,35 +739,29 @@ public class LauncherProvider extends ContentProvider {
addWorkspacesTable(db, false);
}
case 13: {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Insert new column for holding widget provider name
db.execSQL("ALTER TABLE favorites " +
"ADD COLUMN appWidgetProvider TEXT;");
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
// Old version remains, which means we wipe old data
break;
- } finally {
- db.endTransaction();
}
}
case 14: {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Insert new column for holding update timestamp
db.execSQL("ALTER TABLE favorites " +
"ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
db.execSQL("ALTER TABLE workspaceScreens " +
"ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
// Old version remains, which means we wipe old data
break;
- } finally {
- db.endTransaction();
}
}
case 15: {
@@ -870,29 +829,25 @@ public class LauncherProvider extends ContentProvider {
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (oldVersion == 28 && newVersion == 27) {
- // TODO: remove this check. This is only applicable for internal development/testing
- // and for any released version of Launcher.
- return;
+ try {
+ DbDowngradeHelper.parse(mContext.getFileStreamPath(DOWNGRADE_SCHEMA_FILE))
+ .onDowngrade(db, oldVersion, newVersion);
+ } catch (Exception e) {
+ Log.d(TAG, "Unable to downgrade from: " + oldVersion + " to " + newVersion +
+ ". Wiping databse.", e);
+ createEmptyDB(db);
}
- // This shouldn't happen -- throw our hands up in the air and start over.
- Log.w(TAG, "Database version downgrade from: " + oldVersion + " to " + newVersion +
- ". Wiping databse.");
- createEmptyDB(db);
}
/**
* Clears all the data for a fresh start.
*/
public void createEmptyDB(SQLiteDatabase db) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
db.execSQL("DROP TABLE IF EXISTS " + Favorites.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
onCreate(db);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
+ t.commit();
}
}
@@ -912,28 +867,26 @@ public class LauncherProvider extends ContentProvider {
Log.e(TAG, "getAppWidgetIds not supported", e);
return;
}
- try {
- Cursor c = db.query(Favorites.TABLE_NAME,
- new String[] {Favorites.APPWIDGET_ID },
- "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null);
- HashSet<Integer> validWidgets = new HashSet<>();
+ final HashSet<Integer> validWidgets = new HashSet<>();
+ try (Cursor c = db.query(Favorites.TABLE_NAME,
+ new String[] {Favorites.APPWIDGET_ID },
+ "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null)) {
while (c.moveToNext()) {
validWidgets.add(c.getInt(0));
}
- c.close();
-
- for (int widgetId : allWidgets) {
- if (!validWidgets.contains(widgetId)) {
- try {
- FileLog.d(TAG, "Deleting invalid widget " + widgetId);
- host.deleteAppWidgetId(widgetId);
- } catch (RuntimeException e) {
- // Ignore
- }
- }
- }
} catch (SQLException ex) {
Log.w(TAG, "Error getting widgets list", ex);
+ return;
+ }
+ for (int widgetId : allWidgets) {
+ if (!validWidgets.contains(widgetId)) {
+ try {
+ FileLog.d(TAG, "Deleting invalid widget " + widgetId);
+ host.deleteAppWidgetId(widgetId);
+ } catch (RuntimeException e) {
+ // Ignore
+ }
+ }
}
}
@@ -942,22 +895,16 @@ public class LauncherProvider extends ContentProvider {
* launcher activity target with {@link Favorites#ITEM_TYPE_APPLICATION}.
*/
@Thunk void convertShortcutsToLauncherActivities(SQLiteDatabase db) {
- db.beginTransaction();
- Cursor c = null;
- SQLiteStatement updateStmt = null;
-
- try {
- // Only consider the primary user as other users can't have a shortcut.
- long userSerial = getDefaultUserSerial();
- c = db.query(Favorites.TABLE_NAME, new String[] {
- Favorites._ID,
- Favorites.INTENT,
- }, "itemType=" + Favorites.ITEM_TYPE_SHORTCUT + " AND profileId=" + userSerial,
- null, null, null, null);
-
- updateStmt = db.compileStatement("UPDATE favorites SET itemType="
- + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?");
-
+ try (SQLiteTransaction t = new SQLiteTransaction(db);
+ // Only consider the primary user as other users can't have a shortcut.
+ Cursor c = db.query(Favorites.TABLE_NAME,
+ new String[] { Favorites._ID, Favorites.INTENT},
+ "itemType=" + Favorites.ITEM_TYPE_SHORTCUT +
+ " AND profileId=" + getDefaultUserSerial(),
+ null, null, null, null);
+ SQLiteStatement updateStmt = db.compileStatement("UPDATE favorites SET itemType="
+ + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?")
+ ) {
final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);
@@ -979,17 +926,9 @@ public class LauncherProvider extends ContentProvider {
updateStmt.bindLong(1, id);
updateStmt.executeUpdateDelete();
}
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.w(TAG, "Error deduping shortcuts", ex);
- } finally {
- db.endTransaction();
- if (c != null) {
- c.close();
- }
- if (updateStmt != null) {
- updateStmt.close();
- }
}
}
@@ -997,26 +936,17 @@ public class LauncherProvider extends ContentProvider {
* Recreates workspace table and migrates data to the new table.
*/
public boolean recreateWorkspaceTable(SQLiteDatabase db) {
- db.beginTransaction();
- try {
- Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+ final ArrayList<Long> sortedIDs;
+
+ try (Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
new String[] {LauncherSettings.WorkspaceScreens._ID},
null, null, null, null,
- LauncherSettings.WorkspaceScreens.SCREEN_RANK);
- ArrayList<Long> sortedIDs = new ArrayList<Long>();
- long maxId = 0;
- try {
- while (c.moveToNext()) {
- Long id = c.getLong(0);
- if (!sortedIDs.contains(id)) {
- sortedIDs.add(id);
- maxId = Math.max(maxId, id);
- }
- }
- } finally {
- c.close();
+ LauncherSettings.WorkspaceScreens.SCREEN_RANK)) {
+ // Use LinkedHashSet so that ordering is preserved
+ sortedIDs = new ArrayList<>(
+ LauncherDbUtils.iterateCursor(c, 0, new LinkedHashSet<Long>()));
}
-
db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
addWorkspacesTable(db, false);
@@ -1029,21 +959,18 @@ public class LauncherProvider extends ContentProvider {
addModifiedTime(values);
db.insertOrThrow(WorkspaceScreens.TABLE_NAME, null, values);
}
- db.setTransactionSuccessful();
- mMaxScreenId = maxId;
+ t.commit();
+ mMaxScreenId = sortedIDs.isEmpty() ? 0 : Collections.max(sortedIDs);
} catch (SQLException ex) {
// Old version remains, which means we wipe old data
Log.e(TAG, ex.getMessage(), ex);
return false;
- } finally {
- db.endTransaction();
}
return true;
}
@Thunk boolean updateFolderItemsRank(SQLiteDatabase db, boolean addRankColumn) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
if (addRankColumn) {
// Insert new column for holding rank
db.execSQL("ALTER TABLE favorites ADD COLUMN rank INTEGER NOT NULL DEFAULT 0;");
@@ -1062,13 +989,11 @@ public class LauncherProvider extends ContentProvider {
}
c.close();
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
// Old version remains, which means we wipe old data
Log.e(TAG, ex.getMessage(), ex);
return false;
- } finally {
- db.endTransaction();
}
return true;
}
@@ -1078,16 +1003,13 @@ public class LauncherProvider extends ContentProvider {
}
private boolean addIntegerColumn(SQLiteDatabase db, String columnName, long defaultValue) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
db.execSQL("ALTER TABLE favorites ADD COLUMN "
+ columnName + " INTEGER NOT NULL DEFAULT " + defaultValue + ";");
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
return false;
- } finally {
- db.endTransaction();
}
return true;
}
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index b25b256af..87f62eb01 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -22,8 +22,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
-import com.android.launcher3.config.ProviderConfig;
-
/**
* Settings related utilities.
*/
@@ -101,7 +99,7 @@ public class LauncherSettings {
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri.parse("content://" +
- ProviderConfig.AUTHORITY + "/" + TABLE_NAME);
+ LauncherProvider.AUTHORITY + "/" + TABLE_NAME);
/**
* The rank of this screen -- ie. how it is ordered relative to the other screens.
@@ -121,7 +119,7 @@ public class LauncherSettings {
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri.parse("content://" +
- ProviderConfig.AUTHORITY + "/" + TABLE_NAME);
+ LauncherProvider.AUTHORITY + "/" + TABLE_NAME);
/**
* The content:// style URL for a given row, identified by its id.
@@ -131,7 +129,7 @@ public class LauncherSettings {
* @return The unique content URL for the specified row.
*/
public static Uri getContentUri(long id) {
- return Uri.parse("content://" + ProviderConfig.AUTHORITY +
+ return Uri.parse("content://" + LauncherProvider.AUTHORITY +
"/" + TABLE_NAME + "/" + id);
}
@@ -155,6 +153,18 @@ public class LauncherSettings {
}
}
+ static final String itemTypeToString(int type) {
+ switch(type) {
+ case ITEM_TYPE_APPLICATION: return "APP";
+ case ITEM_TYPE_SHORTCUT: return "SHORTCUT";
+ case ITEM_TYPE_FOLDER: return "FOLDER";
+ case ITEM_TYPE_APPWIDGET: return "WIDGET";
+ case ITEM_TYPE_CUSTOM_APPWIDGET: return "CUSTOMWIDGET";
+ case ITEM_TYPE_DEEP_SHORTCUT: return "DEEPSHORTCUT";
+ default: return String.valueOf(type);
+ }
+ }
+
/**
* The screen holding the favorite (if container is CONTAINER_DESKTOP)
* <P>Type: INTEGER</P>
@@ -280,7 +290,7 @@ public class LauncherSettings {
public static final class Settings {
public static final Uri CONTENT_URI = Uri.parse("content://" +
- ProviderConfig.AUTHORITY + "/settings");
+ LauncherProvider.AUTHORITY + "/settings");
public static final String METHOD_CLEAR_EMPTY_DB_FLAG = "clear_empty_db_flag";
public static final String METHOD_WAS_EMPTY_DB_CREATED = "get_empty_db_flag";
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 39c466db8..85467e06a 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -31,8 +31,8 @@ import android.view.animation.AccelerateInterpolator;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimationLayerSet;
+import com.android.launcher3.anim.CircleRevealOutlineProvider;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.CircleRevealOutlineProvider;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.WidgetsContainerView;
diff --git a/src/com/android/launcher3/MainThreadExecutor.java b/src/com/android/launcher3/MainThreadExecutor.java
index 4ca0a59d8..509468233 100644
--- a/src/com/android/launcher3/MainThreadExecutor.java
+++ b/src/com/android/launcher3/MainThreadExecutor.java
@@ -18,14 +18,14 @@ package com.android.launcher3;
import android.os.Looper;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
/**
* An executor service that executes its tasks on the main thread.
*
* Shutting down this executor is not supported.
*/
-public class MainThreadExecutor extends LooperExecuter {
+public class MainThreadExecutor extends LooperExecutor {
public MainThreadExecutor() {
super(Looper.getMainLooper());
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index fb6a611e7..255677a53 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -50,6 +50,7 @@ import android.view.animation.Interpolator;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.util.LauncherEdgeEffect;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import java.util.ArrayList;
@@ -226,11 +227,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * density);
setOnHierarchyChangeListener(this);
setWillNotDraw(false);
- }
- protected void setEdgeGlowColor(int color) {
- mEdgeGlowLeft.setColor(color);
- mEdgeGlowRight.setColor(color);
+ int edgeEffectColor = Themes.getAttrColor(getContext(), android.R.attr.colorEdgeEffect);
+ mEdgeGlowLeft.setColor(edgeEffectColor);
+ mEdgeGlowRight.setColor(edgeEffectColor);
}
protected void setDefaultInterpolator(Interpolator interpolator) {
@@ -1599,7 +1599,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
- Math.abs(velocityX) > mFlingThresholdVelocity;
+ shouldFlingForVelocity(velocityX);
if (!mFreeScroll) {
// In the case that the page is moved far to one direction and then is flung
@@ -1705,6 +1705,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return true;
}
+ protected boolean shouldFlingForVelocity(int velocityX) {
+ return Math.abs(velocityX) > mFlingThresholdVelocity;
+ }
+
private void resetTouchState() {
releaseVelocityTracker();
endReordering();
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index b163464dd..de424aba1 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -80,10 +80,13 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
updateAppWidget(null);
setOnClickListener(mLauncher);
- // Load icon
- PackageItemInfo item = new PackageItemInfo(info.providerName.getPackageName());
- item.user = info.user;
- cache.updateIconInBackground(this, item);
+ if (info.pendingItemInfo == null) {
+ info.pendingItemInfo = new PackageItemInfo(info.providerName.getPackageName());
+ info.pendingItemInfo.user = info.user;
+ cache.updateIconInBackground(this, info.pendingItemInfo);
+ } else {
+ reapplyItemInfo(info.pendingItemInfo);
+ }
}
@Override
diff --git a/src/com/android/launcher3/PromiseAppInfo.java b/src/com/android/launcher3/PromiseAppInfo.java
new file mode 100644
index 000000000..07515d08a
--- /dev/null
+++ b/src/com/android/launcher3/PromiseAppInfo.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import android.content.Intent;
+import android.support.annotation.NonNull;
+
+import com.android.launcher3.compat.PackageInstallerCompat;
+import com.android.launcher3.util.PackageManagerHelper;
+
+public class PromiseAppInfo extends AppInfo {
+
+ public int level = 0;
+
+ public PromiseAppInfo(@NonNull PackageInstallerCompat.PackageInstallInfo installInfo) {
+ componentName = installInfo.componentName;
+ intent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setComponent(componentName)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ }
+
+ @Override
+ public ShortcutInfo makeShortcut() {
+ ShortcutInfo shortcut = new ShortcutInfo(this);
+ shortcut.setInstallProgress(level);
+ // We need to update the component name when the apk is installed
+ shortcut.status |= ShortcutInfo.FLAG_AUTOINSTALL_ICON;
+ // Since the user is manually placing it on homescreen, it should not be auto-removed later
+ shortcut.status |= ShortcutInfo.FLAG_RESTORE_STARTED;
+ return shortcut;
+ }
+
+ public Intent getMarketIntent() {
+ return PackageManagerHelper.getMarketIntent(componentName.getPackageName());
+ }
+}
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 6f0417c08..f0d9367af 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -45,10 +45,10 @@ public class ShortcutInfo extends ItemInfoWithIcon {
* be present along with {@link #FLAG_RESTORED_ICON}, and is set during default layout
* parsing.
*/
- public static final int FLAG_AUTOINTALL_ICON = 2; //0B10;
+ public static final int FLAG_AUTOINSTALL_ICON = 2; //0B10;
/**
- * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINTALL_ICON}
+ * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINSTALL_ICON}
* is set, then the icon is either being installed or is in a broken state.
*/
public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100;
@@ -185,7 +185,7 @@ public class ShortcutInfo extends ItemInfoWithIcon {
public final boolean isPromise() {
- return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINTALL_ICON);
+ return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON);
}
public int getInstallProgress() {
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 0fac29f30..45c14d6bb 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -28,10 +28,13 @@ public class UninstallDropTarget extends ButtonDropTarget {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ setupUi();
+ }
+
+ protected void setupUi() {
// Get the hover color
mHoverColor = getResources().getColor(R.color.uninstall_target_hover_tint);
-
- setDrawable(R.drawable.ic_uninstall_launcher);
+ setDrawable(R.drawable.ic_uninstall_shadow);
}
@Override
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 207a7d4af..54e7dd2bc 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -51,7 +52,7 @@ import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -61,7 +62,6 @@ import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
-import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -570,7 +570,7 @@ public final class Utilities {
try {
c.close();
} catch (IOException e) {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
Log.d(TAG, "Error closing", e);
}
}
@@ -646,4 +646,28 @@ public final class Utilities {
hashSet.add(elem);
return hashSet;
}
+
+ /**
+ * @return creates a new alpha mask bitmap out of an existing bitmap
+ */
+ public static Bitmap convertToAlphaMask(Bitmap b, float applyAlpha) {
+ Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8);
+ Canvas c = new Canvas(a);
+ Paint paint = new Paint();
+ paint.setAlpha((int) (255f * applyAlpha));
+ c.drawBitmap(b, 0f, 0f, paint);
+ return a;
+ }
+
+ /**
+ * @return a new white 1x1 bitmap with ALPHA_8
+ */
+ public static Bitmap createOnePixBitmap() {
+ Bitmap a = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+ Canvas c = new Canvas(a);
+ Paint paint = new Paint();
+ paint.setColor(Color.WHITE);
+ c.drawPaint(paint);
+ return a;
+ }
}
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index c525cd4bc..f66995f70 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -27,7 +27,6 @@ import android.os.CancellationSignal;
import android.os.Handler;
import android.os.UserHandle;
import android.support.annotation.Nullable;
-import android.support.v4.graphics.ColorUtils;
import android.util.Log;
import android.util.LongSparseArray;
@@ -388,10 +387,10 @@ public class WidgetPreviewLoader {
drawable.setBounds(x, 0, x + previewWidth, previewHeight);
drawable.draw(c);
} else {
- final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
- RectF boxRect = drawBoxWithShadow(c, p, previewWidth, previewHeight);
+ RectF boxRect = drawBoxWithShadow(c, previewWidth, previewHeight);
// Draw horizontal and vertical lines to represent individual columns.
+ final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(mContext.getResources()
.getDimension(R.dimen.widget_preview_cell_divider_width));
@@ -431,7 +430,7 @@ public class WidgetPreviewLoader {
return preview;
}
- private RectF drawBoxWithShadow(Canvas c, Paint p, int width, int height) {
+ private RectF drawBoxWithShadow(Canvas c, int width, int height) {
Resources res = mContext.getResources();
float shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur);
float keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance);
@@ -439,19 +438,7 @@ public class WidgetPreviewLoader {
RectF bounds = new RectF(shadowBlur, shadowBlur,
width - shadowBlur, height - shadowBlur - keyShadowDistance);
- p.setColor(Color.WHITE);
-
- // Key shadow
- p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
- ShadowGenerator.KEY_SHADOW_ALPHA << 24);
- c.drawRoundRect(bounds, corner, corner, p);
-
- // Ambient shadow
- p.setShadowLayer(shadowBlur, 0, 0,
- ColorUtils.setAlphaComponent(Color.BLACK, ShadowGenerator.AMBIENT_SHADOW_ALPHA));
- c.drawRoundRect(bounds, corner, corner, p);
-
- p.clearShadowLayer();
+ ShadowGenerator.drawShadow(c, bounds, Color.WHITE, shadowBlur, keyShadowDistance, corner);
return bounds;
}
@@ -478,8 +465,7 @@ public class WidgetPreviewLoader {
c.setBitmap(preview);
c.drawColor(0, PorterDuff.Mode.CLEAR);
}
- Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
- RectF boxRect = drawBoxWithShadow(c, p, size, size);
+ RectF boxRect = drawBoxWithShadow(c, size, size);
Bitmap icon = LauncherIcons.createScaledBitmapWithoutShadow(
mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext, Build.VERSION_CODES.O);
@@ -487,7 +473,8 @@ public class WidgetPreviewLoader {
boxRect.set(0, 0, iconSize, iconSize);
boxRect.offset(padding, padding);
- c.drawBitmap(icon, src, boxRect, p);
+ c.drawBitmap(icon, src, boxRect,
+ new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
c.setBitmap(null);
return preview;
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 36f2880cb..b3dd7ac60 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -43,6 +43,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
import android.util.SparseArray;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
@@ -64,7 +65,6 @@ import com.android.launcher3.anim.AnimationLayerSet;
import com.android.launcher3.badge.FolderBadgeInfo;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
@@ -529,8 +529,6 @@ public class Workspace extends PagedView
// Set the wallpaper dimensions when Launcher starts up
setWallpaperDimension();
-
- setEdgeGlowColor(getResources().getColor(R.color.workspace_edge_effect_color));
}
@Override
@@ -623,7 +621,7 @@ public class Workspace extends PagedView
if (qsb == null) {
// In transposed layout, we add the QSB in the Grid. As workspace does not touch the
// edges, we do not need a full width QSB.
- qsb = mLauncher.getLayoutInflater().inflate(
+ qsb = LayoutInflater.from(getContext()).inflate(
mLauncher.getDeviceProfile().isVerticalBarLayout()
? R.layout.qsb_container : R.layout.qsb_blocker_view,
firstPage, false);
@@ -709,7 +707,7 @@ public class Workspace extends PagedView
// Inflate the cell layout, but do not add it automatically so that we can get the newly
// created CellLayout.
- CellLayout newScreen = (CellLayout) mLauncher.getLayoutInflater().inflate(
+ CellLayout newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
R.layout.workspace_screen, this, false /* attachToRoot */);
newScreen.setOnLongClickListener(mLongClickListener);
newScreen.setOnClickListener(mLauncher);
@@ -727,7 +725,7 @@ public class Workspace extends PagedView
public void createCustomContentContainer() {
CellLayout customScreen = (CellLayout)
- mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, this, false);
+ LayoutInflater.from(getContext()).inflate(R.layout.workspace_screen, this, false);
customScreen.disableDragTarget();
customScreen.disableJailContent();
@@ -1465,6 +1463,13 @@ public class Workspace extends PagedView
}
}
+ @Override
+ protected boolean shouldFlingForVelocity(int velocityX) {
+ // When the overlay is moving, the fling or settle transition is controlled by the overlay.
+ return Float.compare(mOverlayTranslation, 0) == 0 &&
+ super.shouldFlingForVelocity(velocityX);
+ }
+
private final Interpolator mAlphaInterpolator = new DecelerateInterpolator(3f);
/**
@@ -2620,7 +2625,7 @@ public class Workspace extends PagedView
CellLayout parentCell = getParentCellLayoutForView(cell);
if (parentCell != null) {
parentCell.removeView(cell);
- } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ } else if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new NullPointerException("mDragInfo.cell has null parent");
}
addInScreen(cell, container, screenId, mTargetCell[0], mTargetCell[1],
@@ -2953,7 +2958,7 @@ public class Workspace extends PagedView
ItemInfo item = d.dragInfo;
if (item == null) {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new NullPointerException("DragObject has null info");
}
return;
@@ -3610,7 +3615,7 @@ public class Workspace extends PagedView
mDragInfo.container, mDragInfo.screenId);
if (cellLayout != null) {
cellLayout.onDropChild(mDragInfo.cell);
- } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ } else if (FeatureFlags.IS_DOGFOOD_BUILD) {
throw new RuntimeException("Invalid state: cellLayout == null in "
+ "Workspace#onDropCompleted. Please file a bug. ");
};
@@ -3636,7 +3641,7 @@ public class Workspace extends PagedView
CellLayout parentCell = getParentCellLayoutForView(v);
if (parentCell != null) {
parentCell.removeView(v);
- } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ } else if (FeatureFlags.IS_DOGFOOD_BUILD) {
// When an app is uninstalled using the drop target, we wait until resume to remove
// the icon. We also remove all the corresponding items from the workspace at
// {@link Launcher#bindComponentsRemoved}. That call can come before or after
diff --git a/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java b/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java
index d271f1d4e..9c23c1980 100644
--- a/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java
@@ -17,8 +17,8 @@
package com.android.launcher3.accessibility;
import com.android.launcher3.CellLayout;
-import com.android.launcher3.folder.FolderPagedView;
import com.android.launcher3.R;
+import com.android.launcher3.folder.FolderPagedView;
/**
* Implementation of {@link DragAndDropAccessibilityDelegate} to support DnD in a folder.
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index a476650c9..e8127c45f 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -18,7 +18,6 @@ import com.android.launcher3.AppInfo;
import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
-import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.FolderInfo;
@@ -27,7 +26,6 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetHostView;
import com.android.launcher3.LauncherAppWidgetInfo;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
@@ -37,6 +35,7 @@ import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.folder.Folder;
+import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.util.Thunk;
import java.util.ArrayList;
diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
index b784fe7f8..2ad0edbbc 100644
--- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
@@ -22,7 +22,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index 9a23aa813..e6f120fe6 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -27,9 +27,9 @@ import com.android.launcher3.CellLayout;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DragType;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DragType;
import com.android.launcher3.dragndrop.DragLayer;
/**
diff --git a/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java b/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
index c71bc3166..54c5bd0b2 100644
--- a/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
+++ b/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
@@ -25,6 +25,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
+import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
/**
@@ -119,7 +120,8 @@ public class AllAppsBackgroundDrawable extends Drawable {
int finalAlphaI = (int) (finalAlpha * 255f);
if (getAlpha() != finalAlphaI) {
mBackgroundAnim = cancelAnimator(mBackgroundAnim);
- mBackgroundAnim = ObjectAnimator.ofInt(this, "alpha", finalAlphaI);
+ mBackgroundAnim = ObjectAnimator.ofInt(this, LauncherAnimUtils.DRAWABLE_ALPHA,
+ finalAlphaI);
mBackgroundAnim.setDuration(duration);
mBackgroundAnim.start();
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 2c7d15629..d9ee2c55a 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -20,15 +20,9 @@ import android.graphics.Color;
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;
-import android.text.SpannableString;
import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.text.method.TextKeyListener;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -42,25 +36,21 @@ import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
-import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Insettable;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
+import com.android.launcher3.PromiseAppInfo;
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;
-import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
-import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -68,7 +58,7 @@ import java.util.Set;
* The all apps view container.
*/
public class AllAppsContainerView extends BaseContainerView implements DragSource,
- View.OnLongClickListener, AllAppsSearchBarController.Callbacks, Insettable {
+ View.OnLongClickListener, Insettable {
private final Launcher mLauncher;
private final AlphabeticalAppsList mApps;
@@ -76,12 +66,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
private final RecyclerView.LayoutManager mLayoutManager;
private AllAppsRecyclerView mAppsRecyclerView;
- private AllAppsSearchBarController mSearchBarController;
-
+ private SearchUiManager mSearchUiManager;
private View mSearchContainer;
- private int mSearchContainerMinHeight;
- private ExtendedEditText mSearchInput;
- private HeaderElevationController mElevationController;
private SpannableStringBuilder mSearchQueryBuilder = null;
@@ -105,8 +91,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
mApps.setAdapter(mAdapter);
mLayoutManager = mAdapter.getLayoutManager();
mSearchQueryBuilder = new SpannableStringBuilder();
- mSearchContainerMinHeight
- = getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);
Selection.setSelection(mSearchQueryBuilder, 0);
}
@@ -148,7 +132,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
*/
public void addApps(List<AppInfo> apps) {
mApps.addApps(apps);
- mSearchBarController.refreshSearchResult();
+ mSearchUiManager.refreshSearchResult();
}
/**
@@ -156,42 +140,26 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
*/
public void updateApps(List<AppInfo> apps) {
mApps.updateApps(apps);
- mSearchBarController.refreshSearchResult();
- }
-
- /**
- * Removes some apps from the list.
- */
- public void removeApps(List<AppInfo> apps) {
- mApps.removeApps(apps);
- mSearchBarController.refreshSearchResult();
+ mSearchUiManager.refreshSearchResult();
}
- public void setSearchBarVisible(boolean visible) {
- if (visible) {
- mSearchBarController.setVisibility(View.VISIBLE);
- } else {
- mSearchBarController.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
- * Sets the search bar that shows above the a-z list.
- */
- public void setSearchBarController(AllAppsSearchBarController searchController) {
- if (mSearchBarController != null) {
- throw new RuntimeException("Expected search bar controller to only be set once");
+ public void updatePromiseAppProgress(PromiseAppInfo app) {
+ int childCount = mAppsRecyclerView.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = mAppsRecyclerView.getChildAt(i);
+ if (child instanceof BubbleTextView && child.getTag() == app) {
+ BubbleTextView bubbleTextView = (BubbleTextView) child;
+ bubbleTextView.applyProgressLevel(app.level);
+ }
}
- mSearchBarController = searchController;
- mSearchBarController.initialize(mApps, mSearchInput, mLauncher, this);
- mAdapter.setSearchController(mSearchBarController);
}
/**
- * Scrolls this list view to the top.
+ * Removes some apps from the list.
*/
- public void scrollToTop() {
- mAppsRecyclerView.scrollToTop();
+ public void removeApps(List<AppInfo> apps) {
+ mApps.removeApps(apps);
+ mSearchUiManager.refreshSearchResult();
}
/**
@@ -226,9 +194,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
* Focuses the search field and begins an app search.
*/
public void startAppsSearch() {
- if (mSearchBarController != null) {
- mSearchBarController.focusSearchField();
- }
+ mSearchUiManager.startAppsSearch();
}
/**
@@ -236,9 +202,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
*/
public void reset() {
// Reset the search bar and base recycler view after transitioning home
- scrollToTop();
- mSearchBarController.reset();
- mAppsRecyclerView.reset();
+ mAppsRecyclerView.scrollToTop();
+ mSearchUiManager.reset();
}
@Override
@@ -256,28 +221,17 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
}
});
- mSearchContainer = findViewById(R.id.search_container);
- mSearchInput = (ExtendedEditText) findViewById(R.id.search_box_input);
-
- // Update the hint to contain the icon.
- // Prefix the original hint with two spaces. The first space gets replaced by the icon
- // using span. The second space is used for a singe space character between the hint
- // and the icon.
- SpannableString spanned = new SpannableString(" " + mSearchInput.getHint());
- spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
- 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
- mSearchInput.setHint(spanned);
-
- mElevationController = new HeaderElevationController(mSearchContainer);
-
// Load the all apps recycler view
mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
mAppsRecyclerView.setApps(mApps);
mAppsRecyclerView.setLayoutManager(mLayoutManager);
mAppsRecyclerView.setAdapter(mAdapter);
mAppsRecyclerView.setHasFixedSize(true);
- mAppsRecyclerView.addOnScrollListener(mElevationController);
- mAppsRecyclerView.setElevationController(mElevationController);
+
+ mSearchContainer = findViewById(R.id.search_container);
+ mSearchUiManager = (SearchUiManager) mSearchContainer;
+ mSearchUiManager.initialize(mApps, mAppsRecyclerView);
+
FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mAppsRecyclerView);
mAppsRecyclerView.addItemDecoration(focusedItemDecorator);
@@ -291,18 +245,21 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
}
}
+ public SearchUiManager getSearchUiManager() {
+ return mSearchUiManager;
+ }
+
@Override
public View getTouchDelegateTargetView() {
return mAppsRecyclerView;
}
@Override
- public void onBoundsChanged(Rect newBounds) { }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
DeviceProfile grid = mLauncher.getDeviceProfile();
+ // Update the number of items in the grid before we measure the view
grid.updateAppsViewNumCols();
+
if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
if (mNumAppsPerRow != grid.inv.numColumns ||
mNumPredictedAppsPerRow != grid.inv.numColumns) {
@@ -313,22 +270,11 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
mAdapter.setNumAppsPerRow(mNumAppsPerRow);
mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
}
- if (!grid.isVerticalBarLayout()) {
- MarginLayoutParams searchContainerLp =
- (MarginLayoutParams) mSearchContainer.getLayoutParams();
-
- searchContainerLp.height = mLauncher.getDragLayer().getInsets().top
- + mSearchContainerMinHeight;
- mSearchContainer.setLayoutParams(searchContainerLp);
- }
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
// --- remove START when {@code FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP} is enabled. ---
-
- // Update the number of items in the grid before we measure the view
- grid.updateAppsViewNumCols();
if (mNumAppsPerRow != grid.allAppsNumCols ||
mNumPredictedAppsPerRow != grid.allAppsNumPredictiveCols) {
mNumAppsPerRow = grid.allAppsNumCols;
@@ -345,22 +291,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- // Determine if the key event was actual text, if so, focus the search bar and then dispatch
- // the key normally so that it can process this key event
- if (!mSearchBarController.isSearchFieldFocused() &&
- event.getAction() == KeyEvent.ACTION_DOWN) {
- final int unicodeChar = event.getUnicodeChar();
- final boolean isKeyNotWhitespace = unicodeChar > 0 &&
- !Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
- if (isKeyNotWhitespace) {
- boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
- event.getKeyCode(), event);
- if (gotKey && mSearchQueryBuilder.length() > 0) {
- mSearchBarController.focusSearchField();
- }
- }
- }
-
+ mSearchUiManager.preDispatchKeyEvent(event);
return super.dispatchKeyEvent(event);
}
@@ -428,47 +359,21 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
}
@Override
- public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
- if (apps != null) {
- 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();
- }
-
- // Clear the search query
- mSearchQueryBuilder.clear();
- mSearchQueryBuilder.clearSpans();
- Selection.setSelection(mSearchQueryBuilder, 0);
- }
-
- @Override
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
targetParent.containerType = mAppsRecyclerView.getContainerType(v);
}
public boolean shouldRestoreImeState() {
- return !TextUtils.isEmpty(mSearchInput.getText());
+ return mSearchUiManager.shouldRestoreImeState();
}
@Override
public void setInsets(Rect insets) {
DeviceProfile grid = mLauncher.getDeviceProfile();
+ mAppsRecyclerView.setPadding(
+ mAppsRecyclerView.getPaddingLeft(), mAppsRecyclerView.getPaddingTop(),
+ mAppsRecyclerView.getPaddingRight(), insets.bottom);
+
if (grid.isVerticalBarLayout()) {
ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
mlp.leftMargin = insets.left;
@@ -480,7 +385,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
navBarBgLp.height = insets.bottom;
navBarBg.setLayoutParams(navBarBgLp);
- navBarBg.setVisibility(View.VISIBLE);
+ navBarBg.setVisibility(FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
+ ? View.INVISIBLE : View.VISIBLE);
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
index a1ff8223a..e08cb15cd 100644
--- a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
+++ b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
@@ -16,11 +16,7 @@
package com.android.launcher3.allapps;
import android.support.v7.widget.RecyclerView;
-import android.view.View;
-import com.android.launcher3.BaseRecyclerViewFastScrollBar;
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.util.Thunk;
import java.util.HashSet;
@@ -210,7 +206,9 @@ public class AllAppsFastScrollHelper implements AllAppsGridAdapter.BindViewCallb
for (RecyclerView.ViewHolder viewHolder : mTrackedFastScrollViews) {
int pos = viewHolder.getAdapterPosition();
boolean isActive = false;
- if (mCurrentFastScrollSection != null && pos > -1) {
+ if (mCurrentFastScrollSection != null
+ && pos > RecyclerView.NO_POSITION
+ && pos < mApps.getAdapterItems().size()) {
AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(pos);
isActive = item != null &&
mCurrentFastScrollSection.equals(item.sectionName) &&
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 59cac8d26..cfd04e2e0 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -33,13 +33,14 @@ import android.view.ViewGroup;
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.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
+import com.android.launcher3.discovery.AppDiscoveryAppInfo;
import com.android.launcher3.discovery.AppDiscoveryItemView;
+import com.android.launcher3.util.PackageManagerHelper;
import java.util.List;
@@ -160,11 +161,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
}
return extraRows;
}
-
- @Override
- public int getPaddingBottom() {
- return mLauncher.getDragLayer().getInsets().bottom;
- }
}
/**
@@ -199,7 +195,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
private int mAppsPerRow;
private BindViewCallback mBindViewCallback;
- private AllAppsSearchBarController mSearchController;
private OnFocusChangeListener mIconFocusListener;
// The text to show when there are no search results and no market search handler.
@@ -241,10 +236,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
mGridLayoutMgr.setSpanCount(appsPerRow);
}
- public void setSearchController(AllAppsSearchBarController searchController) {
- mSearchController = searchController;
- }
-
public void setIconFocusListener(OnFocusChangeListener focusListener) {
mIconFocusListener = focusListener;
}
@@ -256,7 +247,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
public void setLastSearchQuery(String query) {
Resources res = mLauncher.getResources();
mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query);
- mMarketSearchIntent = mSearchController.createMarketSearchIntent(query);
+ mMarketSearchIntent = PackageManagerHelper.getMarketSearchIntent(mLauncher, query);
}
/**
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 64e2fcb3d..16b2bd1fc 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -53,8 +53,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
private AllAppsBackgroundDrawable mEmptySearchBackground;
private int mEmptySearchBackgroundTopOffset;
- private HeaderElevationController mElevationController;
-
public AllAppsRecyclerView(Context context) {
this(context, null);
}
@@ -85,10 +83,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
mFastScrollHelper = new AllAppsFastScrollHelper(this, apps);
}
- public void setElevationController(HeaderElevationController elevationController) {
- mElevationController = elevationController;
- }
-
/**
* Sets the number of apps per row in this recycler view.
*/
@@ -152,13 +146,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
*/
public void scrollToTop() {
// Ensure we reattach the scrollbar if it was previously detached while fast-scrolling
- if (mScrollbar.isThumbDetached()) {
- mScrollbar.reattachThumbToScroll();
- }
+ mScrollbar.reattachThumbToScroll();
scrollToPosition(0);
- if (mElevationController != null) {
- mElevationController.reset();
- }
}
@Override
@@ -403,21 +392,14 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
return getPaddingTop() + y - offset;
}
- @Override
- protected int getScrollbarTrackHeight() {
- return super.getScrollbarTrackHeight()
- - Launcher.getLauncher(getContext()).getDragLayer().getInsets().bottom;
- }
-
/**
* Returns the available scroll height:
* AvailableScrollHeight = Total height of the all items - last page height
*/
@Override
protected int getAvailableScrollHeight() {
- int paddedHeight = getCurrentScrollY(mApps.getAdapterItems().size(), 0);
- int totalHeight = paddedHeight + getPaddingBottom();
- return totalHeight - getScrollbarTrackHeight();
+ return getCurrentScrollY(mApps.getAdapterItems().size(), 0)
+ - getHeight() + getPaddingBottom();
}
/**
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
index 6587ad78c..517dc947e 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
@@ -20,7 +20,6 @@ import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import com.android.launcher3.BubbleTextView;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 30ed180e7..7c6ff5120 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -22,6 +22,10 @@ import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dynamicui.ExtractedColors;
+import com.android.launcher3.graphics.GradientView;
+import com.android.launcher3.graphics.ScrimView;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.Themes;
@@ -38,12 +42,13 @@ import com.android.launcher3.util.TouchController;
* closer to top or closer to the page indicator.
*/
public class AllAppsTransitionController implements TouchController, VerticalPullDetector.Listener,
- View.OnLayoutChangeListener {
+ ExtractedColors.OnChangeListener, SearchUiManager.OnScrollRangeChangeListener {
private static final String TAG = "AllAppsTrans";
private static final boolean DBG = false;
- private final Interpolator mAccelInterpolator = new AccelerateInterpolator(2f);
+ private final Interpolator mWorkspaceAccelnterpolator = new AccelerateInterpolator(2f);
+ private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(.5f);
private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f);
private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator();
private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator
@@ -91,6 +96,8 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
// Used in discovery bounce animation to provide the transition without workspace changing.
private boolean mIsTranslateWithoutWorkspace = false;
private AnimatorSet mDiscoBounceAnimation;
+ private GradientView mGradientView;
+ private ScrimView mScrimView;
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
@@ -101,6 +108,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
mEvaluator = new ArgbEvaluator();
mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary);
+ mLauncher.getExtractedColors().addOnChangeListener(this);
}
@Override
@@ -247,7 +255,9 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
if (!mLauncher.isAllAppsVisible()) {
mLauncher.tryAndUpdatePredictedApps();
mAppsView.setVisibility(View.VISIBLE);
- mAppsView.setRevealDrawableColor(mHotseatBackgroundColor);
+ if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ mAppsView.setRevealDrawableColor(mHotseatBackgroundColor);
+ }
}
}
}
@@ -263,6 +273,37 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
mLauncher.activateLightSystemBars(forceLight, true /* statusBar */, true /* navBar */);
}
+ private void updateAllAppsBg(float progress) {
+ // gradient
+ if (mGradientView == null) {
+ mGradientView = (GradientView) mLauncher.findViewById(R.id.gradient_bg);
+ mGradientView.setVisibility(View.VISIBLE);
+ onExtractedColorsChanged();
+ }
+ mGradientView.setProgress(progress);
+
+ // scrim
+ if (mScrimView == null) {
+ mScrimView = (ScrimView) mLauncher.findViewById(R.id.scrim_bg);
+ mScrimView.setVisibility(View.VISIBLE);
+ }
+ mScrimView.setProgress(progress);
+ }
+
+ @Override
+ public void onExtractedColorsChanged() {
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ if (mGradientView != null) {
+ int color1 = mLauncher.getExtractedColors()
+ .getColor(ExtractedColors.ALLAPPS_GRADIENT_MAIN_INDEX);
+ int color2 = mLauncher.getExtractedColors()
+ .getColor(ExtractedColors.ALLAPPS_GRADIENT_SECONDARY_INDEX);
+ mGradientView.onExtractedColorsChanged(color1, color2);
+ mGradientView.requestLayout();
+ }
+ }
+ }
+
/**
* @param progress value between 0 and 1, 0 shows all apps and 1 shows workspace
*/
@@ -273,31 +314,37 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
float workspaceHotseatAlpha = Utilities.boundToRange(progress, 0f, 1f);
float alpha = 1 - workspaceHotseatAlpha;
- float interpolation = mAccelInterpolator.getInterpolation(workspaceHotseatAlpha);
+ float workspaceAlpha = mWorkspaceAccelnterpolator.getInterpolation(workspaceHotseatAlpha);
+ float hotseatAlpha = mHotseatAccelInterpolator.getInterpolation(workspaceHotseatAlpha);
int color = (Integer) mEvaluator.evaluate(mDecelInterpolator.getInterpolation(alpha),
mHotseatBackgroundColor, mAllAppsBackgroundColor);
int bgAlpha = Color.alpha((int) mEvaluator.evaluate(alpha,
mHotseatBackgroundColor, mAllAppsBackgroundColor));
- mAppsView.setRevealDrawableColor(ColorUtils.setAlphaComponent(color, bgAlpha));
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ updateAllAppsBg(alpha);
+ } else {
+ mAppsView.setRevealDrawableColor(ColorUtils.setAlphaComponent(color, bgAlpha));
+ }
+
mAppsView.getContentView().setAlpha(alpha);
mAppsView.setTranslationY(shiftCurrent);
if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
mWorkspace.setHotseatTranslationAndAlpha(Workspace.Direction.Y, -mShiftRange + shiftCurrent,
- interpolation);
+ hotseatAlpha);
} else {
mWorkspace.setHotseatTranslationAndAlpha(Workspace.Direction.Y,
PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent),
- interpolation);
+ hotseatAlpha);
}
if (mIsTranslateWithoutWorkspace) {
return;
}
mWorkspace.setWorkspaceYTranslationAndAlpha(
- PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), interpolation);
+ PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), workspaceAlpha);
if (!mDetector.isDraggingState()) {
mContainerVelocity = mDetector.computeVelocity(shiftCurrent - shiftPrevious,
@@ -486,21 +533,15 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
mAppsView = appsView;
mHotseat = hotseat;
mWorkspace = workspace;
- mHotseat.addOnLayoutChangeListener(this);
mHotseat.bringToFront();
mCaretController = new AllAppsCaretController(
mWorkspace.getPageIndicator().getCaretDrawable(), mLauncher);
+ mAppsView.getSearchUiManager().addOnScrollRangeChangeListener(this);
}
@Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- mShiftRange = top;
- } else {
- mShiftRange = bottom;
- }
+ public void onScrollRangeChanged(int scrollRange) {
+ mShiftRange = scrollRange;
setProgress(mProgress);
}
-
}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index f5cf7effb..047441985 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -24,7 +24,7 @@ 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.config.FeatureFlags;
import com.android.launcher3.discovery.AppDiscoveryAppInfo;
import com.android.launcher3.discovery.AppDiscoveryItem;
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
@@ -195,6 +195,8 @@ public class AlphabeticalAppsList {
private int mNumPredictedAppsPerRow;
private int mNumAppRowsInAdapter;
+ private boolean mHasSearchDivider = true;
+
public AlphabeticalAppsList(Context context) {
mLauncher = Launcher.getLauncher(context);
mIndexer = new AlphabeticIndexCompat(context);
@@ -343,6 +345,10 @@ public class AlphabeticalAppsList {
onAppsUpdated();
}
+ public void disableSearchDivider() {
+ mHasSearchDivider = false;
+ }
+
/**
* Updates internals when the set of apps are updated.
*/
@@ -429,8 +435,10 @@ public class AlphabeticalAppsList {
}
}
- // Add the search divider
- mAdapterItems.add(AdapterItem.asSearchDivider(position++));
+ if (mHasSearchDivider) {
+ // Add the search divider
+ mAdapterItems.add(AdapterItem.asSearchDivider(position++));
+ }
// Process the predicted app components
mPredictedApps.clear();
@@ -440,7 +448,7 @@ public class AlphabeticalAppsList {
if (info != null) {
mPredictedApps.add(info);
} else {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
Log.e(TAG, "Predicted app not found: " + ck);
}
}
diff --git a/src/com/android/launcher3/allapps/DefaultAppSearchController.java b/src/com/android/launcher3/allapps/DefaultAppSearchController.java
deleted file mode 100644
index 57747e367..000000000
--- a/src/com/android/launcher3/allapps/DefaultAppSearchController.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-/**
- * The default search controller.
- */
-public class DefaultAppSearchController extends AllAppsSearchBarController {
-
- public DefaultAppSearchAlgorithm onInitializeSearch() {
- return new DefaultAppSearchAlgorithm(mApps.getApps());
- }
-}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
new file mode 100644
index 000000000..0d013c73f
--- /dev/null
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -0,0 +1,68 @@
+/*
+ * 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.allapps;
+
+import android.view.KeyEvent;
+
+/**
+ * Interface for controlling the Apps search UI.
+ */
+public interface SearchUiManager {
+
+ /**
+ * Initializes the search manager.
+ */
+ void initialize(AlphabeticalAppsList appsList, AllAppsRecyclerView recyclerView);
+
+ /**
+ * Notifies the search manager that the apps-list has changed and the search UI should be
+ * updated accordingly.
+ */
+ void refreshSearchResult();
+
+ /**
+ * Notifies the search manager to close any active search session.
+ */
+ void reset();
+
+ /**
+ * Called before dispatching a key event, in case the search manager wants to initialize
+ * some UI beforehand.
+ */
+ void preDispatchKeyEvent(KeyEvent keyEvent);
+
+ /**
+ * Returns true if the IME should be brought back.
+ * TODO: Remove when removing support for opening all-apps in search mode.
+ */
+ boolean shouldRestoreImeState();
+
+ /**
+ * Starts the search UI
+ * TODO: Remove when removing support for opening all-apps in search mode.
+ */
+ void startAppsSearch();
+
+ void addOnScrollRangeChangeListener(OnScrollRangeChangeListener listener);
+
+ /**
+ * Callback for listening to changes in the vertical scroll range when opening all-apps.
+ */
+ interface OnScrollRangeChangeListener {
+
+ void onScrollRangeChanged(int scrollRange);
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index c7ba3abc6..547d9e185 100644
--- a/src/com/android/launcher3/allapps/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -13,12 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
import android.content.Context;
-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;
@@ -34,16 +31,18 @@ import android.widget.TextView.OnEditorActionListener;
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.AlphabeticalAppsList;
import com.android.launcher3.discovery.AppDiscoveryItem;
import com.android.launcher3.discovery.AppDiscoveryUpdateState;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.PackageManagerHelper;
import java.util.ArrayList;
/**
* An interface to a search box that AllApps can command.
*/
-public abstract class AllAppsSearchBarController
+public class AllAppsSearchBarController
implements TextWatcher, OnEditorActionListener, ExtendedEditText.OnBackKeyListener {
protected Launcher mLauncher;
@@ -88,9 +87,11 @@ public abstract class AllAppsSearchBarController
}
/**
- * To be implemented by subclasses. This method will get called when the controller is set.
+ * This method will get called when the controller is set.
*/
- protected abstract DefaultAppSearchAlgorithm onInitializeSearch();
+ public DefaultAppSearchAlgorithm onInitializeSearch() {
+ return new DefaultAppSearchAlgorithm(mApps.getApps());
+ }
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -114,7 +115,7 @@ public abstract class AllAppsSearchBarController
}
}
- protected void refreshSearchResult() {
+ public void refreshSearchResult() {
if (TextUtils.isEmpty(mQuery)) {
return;
}
@@ -135,7 +136,8 @@ public abstract class AllAppsSearchBarController
if (query.isEmpty()) {
return false;
}
- return mLauncher.startActivitySafely(v, createMarketSearchIntent(query), null);
+ return mLauncher.startActivitySafely(v,
+ PackageManagerHelper.getMarketSearchIntent(mLauncher, query), null);
}
@Override
@@ -186,29 +188,11 @@ public abstract class AllAppsSearchBarController
}
/**
- * Creates a new market search intent.
- */
- public Intent createMarketSearchIntent(String query) {
- Uri marketSearchUri = Uri.parse("market://search")
- .buildUpon()
- .appendQueryParameter("c", "apps")
- .appendQueryParameter("q", query)
- .build();
- return new Intent(Intent.ACTION_VIEW).setData(marketSearchUri);
- }
-
- /**
* Callback for getting search results.
*/
public interface Callbacks {
/**
- * Called when the bounds of the search bar has changed.
- */
- @Deprecated
- void onBoundsChanged(Rect newBounds);
-
- /**
* Called when the search is complete.
*
* @param apps sorted list of matching components or null if in case of failure.
@@ -220,7 +204,6 @@ public abstract class AllAppsSearchBarController
*/
void clearSearchResult();
-
/**
* Called when the app discovery is providing an update of search, which can either be
* START for starting a new discovery,
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
new file mode 100644
index 000000000..f785e4cdb
--- /dev/null
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -0,0 +1,211 @@
+/*
+ * 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.allapps.search;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.method.TextKeyListener;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.launcher3.ExtendedEditText;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+import com.android.launcher3.allapps.AllAppsRecyclerView;
+import com.android.launcher3.allapps.AlphabeticalAppsList;
+import com.android.launcher3.allapps.SearchUiManager;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.discovery.AppDiscoveryItem;
+import com.android.launcher3.discovery.AppDiscoveryUpdateState;
+import com.android.launcher3.graphics.TintedDrawableSpan;
+import com.android.launcher3.util.ComponentKey;
+
+import java.util.ArrayList;
+
+/**
+ * Layout to contain the All-apps search UI.
+ */
+public class AppsSearchContainerLayout extends FrameLayout
+ implements SearchUiManager, AllAppsSearchBarController.Callbacks {
+
+ private final Launcher mLauncher;
+ private final int mMinHeight;
+ private final AllAppsSearchBarController mSearchBarController;
+ private final SpannableStringBuilder mSearchQueryBuilder;
+ private final HeaderElevationController mElevationController;
+
+ private ExtendedEditText mSearchInput;
+ private AlphabeticalAppsList mApps;
+ private AllAppsRecyclerView mAppsRecyclerView;
+ private AllAppsGridAdapter mAdapter;
+
+ public AppsSearchContainerLayout(Context context) {
+ this(context, null);
+ }
+
+ public AppsSearchContainerLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public AppsSearchContainerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ mLauncher = Launcher.getLauncher(context);
+ mMinHeight = getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);
+ mSearchBarController = new AllAppsSearchBarController();
+ mElevationController = new HeaderElevationController(this);
+
+ mSearchQueryBuilder = new SpannableStringBuilder();
+ Selection.setSelection(mSearchQueryBuilder, 0);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mSearchInput = findViewById(R.id.search_box_input);
+
+ // Update the hint to contain the icon.
+ // Prefix the original hint with two spaces. The first space gets replaced by the icon
+ // using span. The second space is used for a singe space character between the hint
+ // and the icon.
+ SpannableString spanned = new SpannableString(" " + mSearchInput.getHint());
+ spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
+ 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
+ mSearchInput.setHint(spanned);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
+ !mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+ getLayoutParams().height = mLauncher.getDragLayer().getInsets().top + mMinHeight;
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+
+ @Override
+ public void initialize(
+ AlphabeticalAppsList appsList, AllAppsRecyclerView recyclerView) {
+ mApps = appsList;
+ mAppsRecyclerView = recyclerView;
+ mAppsRecyclerView.addOnScrollListener(mElevationController);
+ mAdapter = (AllAppsGridAdapter) mAppsRecyclerView.getAdapter();
+
+ mSearchBarController.initialize(appsList, mSearchInput, mLauncher, this);
+ }
+
+ @Override
+ public void refreshSearchResult() {
+ mSearchBarController.refreshSearchResult();
+ }
+
+ @Override
+ public void reset() {
+ mElevationController.reset();
+ mSearchBarController.reset();
+ }
+
+ @Override
+ public void preDispatchKeyEvent(KeyEvent event) {
+ // Determine if the key event was actual text, if so, focus the search bar and then dispatch
+ // the key normally so that it can process this key event
+ if (!mSearchBarController.isSearchFieldFocused() &&
+ event.getAction() == KeyEvent.ACTION_DOWN) {
+ final int unicodeChar = event.getUnicodeChar();
+ final boolean isKeyNotWhitespace = unicodeChar > 0 &&
+ !Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
+ if (isKeyNotWhitespace) {
+ boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
+ event.getKeyCode(), event);
+ if (gotKey && mSearchQueryBuilder.length() > 0) {
+ mSearchBarController.focusSearchField();
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean shouldRestoreImeState() {
+ return !TextUtils.isEmpty(mSearchInput.getText());
+ }
+
+ @Override
+ public void startAppsSearch() {
+ if (mApps != null) {
+ mSearchBarController.focusSearchField();
+ }
+ }
+
+ @Override
+ public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
+ if (apps != null) {
+ mApps.setOrderedFilter(apps);
+ notifyResultChanged();
+ mAdapter.setLastSearchQuery(query);
+ }
+ }
+
+ @Override
+ public void clearSearchResult() {
+ if (mApps.setOrderedFilter(null)) {
+ notifyResultChanged();
+ }
+
+ // Clear the search query
+ mSearchQueryBuilder.clear();
+ mSearchQueryBuilder.clearSpans();
+ Selection.setSelection(mSearchQueryBuilder, 0);
+ }
+
+ @Override
+ public void onAppDiscoverySearchUpdate(
+ @Nullable AppDiscoveryItem app, @NonNull AppDiscoveryUpdateState state) {
+ if (!mLauncher.isDestroyed()) {
+ mApps.onAppDiscoverySearchUpdate(app, state);
+ notifyResultChanged();
+ }
+ }
+
+ private void notifyResultChanged() {
+ mElevationController.reset();
+ mAppsRecyclerView.onSearchResultsChanged();
+ }
+
+ @Override
+ public void addOnScrollRangeChangeListener(final OnScrollRangeChangeListener listener) {
+ mLauncher.getHotseat().addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+ listener.onScrollRangeChanged(top);
+ } else {
+ listener.onScrollRangeChanged(bottom);
+ }
+ }
+ });
+ }
+}
diff --git a/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
index 06cf9aa71..457b454ef 100644
--- a/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
import android.os.Handler;
diff --git a/src/com/android/launcher3/allapps/HeaderElevationController.java b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
index b167fed33..ab4e88fc8 100644
--- a/src/com/android/launcher3/allapps/HeaderElevationController.java
+++ b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
@@ -1,4 +1,4 @@
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
import android.content.res.Resources;
import android.graphics.Outline;
diff --git a/src/com/android/launcher3/util/CircleRevealOutlineProvider.java b/src/com/android/launcher3/anim/CircleRevealOutlineProvider.java
index 9fe51476d..9fb6b498b 100644
--- a/src/com/android/launcher3/util/CircleRevealOutlineProvider.java
+++ b/src/com/android/launcher3/anim/CircleRevealOutlineProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3.util;
+package com.android.launcher3.anim;
public class CircleRevealOutlineProvider extends RevealOutlineAnimation {
diff --git a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java b/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
index be1e2d644..679e8e32f 100644
--- a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
+++ b/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
@@ -18,8 +18,6 @@ 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.
diff --git a/src/com/android/launcher3/util/PillRevealOutlineProvider.java b/src/com/android/launcher3/anim/PillRevealOutlineProvider.java
index a57d69fab..450f9db9a 100644
--- a/src/com/android/launcher3/util/PillRevealOutlineProvider.java
+++ b/src/com/android/launcher3/anim/PillRevealOutlineProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3.util;
+package com.android.launcher3.anim;
import android.graphics.Rect;
import android.view.ViewOutlineProvider;
diff --git a/src/com/android/launcher3/util/RevealOutlineAnimation.java b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
index 456047775..51d00d947 100644
--- a/src/com/android/launcher3/util/RevealOutlineAnimation.java
+++ b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
@@ -1,4 +1,4 @@
-package com.android.launcher3.util;
+package com.android.launcher3.anim;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -83,4 +83,8 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider {
public void getOutline(View v, Outline outline) {
outline.setRoundRect(mOutline, mOutlineRadius);
}
+
+ public float getRadius() {
+ return mOutlineRadius;
+ }
}
diff --git a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
new file mode 100644
index 000000000..a0d1f8b65
--- /dev/null
+++ b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+/**
+ * A {@link RevealOutlineAnimation} that provides an outline that interpolates between two radii
+ * and two {@link Rect}s.
+ *
+ * An example usage of this provider is an outline that starts out as a circle and ends
+ * as a rounded rectangle.
+ */
+public class RoundedRectRevealOutlineProvider extends RevealOutlineAnimation {
+ private final float mStartRadius;
+ private final float mEndRadius;
+
+ private final Rect mStartRect;
+ private final Rect mEndRect;
+
+ public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect,
+ Rect endRect) {
+ mStartRadius = startRadius;
+ mEndRadius = endRadius;
+ mStartRect = startRect;
+ mEndRect = endRect;
+ }
+
+ @Override
+ public boolean shouldRemoveElevationDuringAnimation() {
+ return true;
+ }
+
+ @Override
+ public void setProgress(float progress) {
+ mOutlineRadius = (1 - progress) * mStartRadius + progress * mEndRadius;
+
+ mOutline.left = (int) ((1 - progress) * mStartRect.left + progress * mEndRect.left);
+ mOutline.top = (int) ((1 - progress) * mStartRect.top + progress * mEndRect.top);
+ mOutline.right = (int) ((1 - progress) * mStartRect.right + progress * mEndRect.right);
+ mOutline.bottom = (int) ((1 - progress) * mStartRect.bottom + progress * mEndRect.bottom);
+ }
+}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index e997a9993..472cfc9ec 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -32,7 +32,7 @@ import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.PackageUserKey;
import java.util.List;
@@ -116,7 +116,7 @@ public abstract class LauncherAppsCompat {
}
} else {
// Block the worker thread until the accept() is called.
- new LooperExecuter(LauncherModel.getWorkerLooper()).execute(new Runnable() {
+ new LooperExecutor(LauncherModel.getWorkerLooper()).execute(new Runnable() {
@Override
public void run() {
try {
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompat.java b/src/com/android/launcher3/compat/PackageInstallerCompat.java
index c7fe0cec8..112cca540 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompat.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompat.java
@@ -16,9 +16,13 @@
package com.android.launcher3.compat;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageInstaller;
+import android.support.annotation.NonNull;
import java.util.HashMap;
+import java.util.List;
public abstract class PackageInstallerCompat {
@@ -46,19 +50,34 @@ public abstract class PackageInstallerCompat {
public abstract void onStop();
public static final class PackageInstallInfo {
+ public final ComponentName componentName;
public final String packageName;
+ public final int state;
+ public final int progress;
- public int state;
- public int progress;
-
- public PackageInstallInfo(String packageName) {
- this.packageName = packageName;
+ private PackageInstallInfo(@NonNull PackageInstaller.SessionInfo info) {
+ this.state = STATUS_INSTALLING;
+ this.packageName = info.getAppPackageName();
+ this.componentName = new ComponentName(packageName, "");
+ this.progress = (int) (info.getProgress() * 100f);
}
public PackageInstallInfo(String packageName, int state, int progress) {
- this.packageName = packageName;
this.state = state;
+ this.packageName = packageName;
+ this.componentName = new ComponentName(packageName, "");
this.progress = progress;
}
+
+ public static PackageInstallInfo fromInstallingState(PackageInstaller.SessionInfo info) {
+ return new PackageInstallInfo(info);
+ }
+
+ public static PackageInstallInfo fromState(int state, String packageName) {
+ return new PackageInstallInfo(packageName, state, 0 /* progress */);
+ }
+
}
+
+ public abstract List<PackageInstaller.SessionInfo> getAllVerifiedSessions();
}
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index b87582f55..1ffd3da01 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -17,34 +17,44 @@
package com.android.launcher3.compat;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionCallback;
import android.content.pm.PackageInstaller.SessionInfo;
import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.SparseArray;
import com.android.launcher3.IconCache;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.Thunk;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
public class PackageInstallerCompatVL extends PackageInstallerCompat {
+ private static final boolean DEBUG = false;
+
@Thunk final SparseArray<String> mActiveSessions = new SparseArray<>();
@Thunk final PackageInstaller mInstaller;
private final IconCache mCache;
private final Handler mWorker;
+ private final Context mAppContext;
+ private final HashMap<String,Boolean> mSessionVerifiedMap = new HashMap<>();
PackageInstallerCompatVL(Context context) {
+ mAppContext = context.getApplicationContext();
mInstaller = context.getPackageManager().getPackageInstaller();
mCache = LauncherAppState.getInstance(context).getIconCache();
mWorker = new Handler(LauncherModel.getWorkerLooper());
-
mInstaller.registerSessionCallback(mCallback, mWorker);
}
@@ -52,7 +62,7 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
public HashMap<String, Integer> updateAndGetActiveSessionCache() {
HashMap<String, Integer> activePackages = new HashMap<>();
UserHandle user = Process.myUserHandle();
- for (SessionInfo info : mInstaller.getAllSessions()) {
+ for (SessionInfo info : getAllVerifiedSessions()) {
addSessionInfoToCache(info, user);
if (info.getAppPackageName() != null) {
activePackages.put(info.getAppPackageName(), (int) (info.getProgress() * 100));
@@ -86,7 +96,14 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
@Override
public void onCreated(int sessionId) {
- pushSessionDisplayToLauncher(sessionId);
+ SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId);
+ if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS && sessionInfo != null) {
+ LauncherAppState app = LauncherAppState.getInstanceNoCreate();
+ if (app != null) {
+ app.getModel().onInstallSessionCreated(
+ PackageInstallInfo.fromInstallingState(sessionInfo));
+ }
+ }
}
@Override
@@ -97,18 +114,17 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
mActiveSessions.remove(sessionId);
if (packageName != null) {
- sendUpdate(new PackageInstallInfo(packageName,
- success ? STATUS_INSTALLED : STATUS_FAILED, 0));
+ sendUpdate(PackageInstallInfo.fromState(
+ success ? STATUS_INSTALLED : STATUS_FAILED,
+ packageName));
}
}
@Override
public void onProgressChanged(int sessionId, float progress) {
- SessionInfo session = mInstaller.getSessionInfo(sessionId);
+ SessionInfo session = verify(mInstaller.getSessionInfo(sessionId));
if (session != null && session.getAppPackageName() != null) {
- sendUpdate(new PackageInstallInfo(session.getAppPackageName(),
- STATUS_INSTALLING,
- (int) (session.getProgress() * 100)));
+ sendUpdate(PackageInstallInfo.fromInstallingState(session));
}
}
@@ -120,16 +136,48 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
pushSessionDisplayToLauncher(sessionId);
}
- private void pushSessionDisplayToLauncher(int sessionId) {
- SessionInfo session = mInstaller.getSessionInfo(sessionId);
+ private SessionInfo pushSessionDisplayToLauncher(int sessionId) {
+ SessionInfo session = verify(mInstaller.getSessionInfo(sessionId));
if (session != null && session.getAppPackageName() != null) {
+ mActiveSessions.put(sessionId, session.getAppPackageName());
addSessionInfoToCache(session, Process.myUserHandle());
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
-
if (app != null) {
app.getModel().updateSessionDisplayInfo(session.getAppPackageName());
}
+ return session;
}
+ return null;
}
};
+
+ private PackageInstaller.SessionInfo verify(PackageInstaller.SessionInfo sessionInfo) {
+ if (sessionInfo == null
+ || sessionInfo.getInstallerPackageName() == null
+ || TextUtils.isEmpty(sessionInfo.getAppPackageName())) {
+ return null;
+ }
+ String pkg = sessionInfo.getInstallerPackageName();
+ synchronized (mSessionVerifiedMap) {
+ if (!mSessionVerifiedMap.containsKey(pkg)) {
+ LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mAppContext);
+ boolean hasSystemFlag = launcherApps.getApplicationInfo(pkg,
+ ApplicationInfo.FLAG_SYSTEM, Process.myUserHandle()) != null;
+ mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag);
+ }
+ }
+ return mSessionVerifiedMap.get(pkg) ? sessionInfo : null;
+ }
+
+ @Override
+ public List<SessionInfo> getAllVerifiedSessions() {
+ List<SessionInfo> list = new ArrayList<>(mInstaller.getAllSessions());
+ Iterator<SessionInfo> it = list.iterator();
+ while (it.hasNext()) {
+ if (verify(it.next()) == null) {
+ it.remove();
+ }
+ }
+ return list;
+ }
}
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItem.java b/src/com/android/launcher3/discovery/AppDiscoveryItem.java
index 09c91acc6..2e48b25e0 100644
--- a/src/com/android/launcher3/discovery/AppDiscoveryItem.java
+++ b/src/com/android/launcher3/discovery/AppDiscoveryItem.java
@@ -16,7 +16,6 @@
package com.android.launcher3.discovery;
-import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
diff --git a/src/com/android/launcher3/dragndrop/DragOptions.java b/src/com/android/launcher3/dragndrop/DragOptions.java
index 230fa2d4a..9433aadc7 100644
--- a/src/com/android/launcher3/dragndrop/DragOptions.java
+++ b/src/com/android/launcher3/dragndrop/DragOptions.java
@@ -17,8 +17,6 @@
package com.android.launcher3.dragndrop;
import android.graphics.Point;
-import android.support.annotation.CallSuper;
-import android.view.View;
import com.android.launcher3.DropTarget;
diff --git a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
index 36a0292da..e36f607de 100644
--- a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
+++ b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
@@ -4,7 +4,6 @@ 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;
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index f94d442e0..349b4fff6 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -21,6 +21,7 @@ import android.app.IntentService;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
@@ -61,6 +62,13 @@ public class ColorExtractionService extends IntentService {
if (wallpaperManager.getWallpaperInfo() != null) {
// We can't extract colors from live wallpapers, so just use the default color always.
extractedColors.updateHotseatPalette(null);
+
+ if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ extractedColors.updateWallpaperThemePalette(null);
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ extractedColors.updateAllAppsGradientPalette(this);
+ }
+ }
} else {
// We extract colors for the hotseat and status bar separately,
// since they only consider part of the wallpaper.
@@ -69,6 +77,13 @@ public class ColorExtractionService extends IntentService {
if (FeatureFlags.LIGHT_STATUS_BAR) {
extractedColors.updateStatusBarPalette(getStatusBarPalette());
}
+
+ if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ extractedColors.updateWallpaperThemePalette(getWallpaperPalette());
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ extractedColors.updateAllAppsGradientPalette(this);
+ }
+ }
}
// Save the extracted colors and wallpaper id to LauncherProvider.
@@ -140,4 +155,23 @@ public class ColorExtractionService extends IntentService {
.clearFilters()
.generate();
}
+
+ @TargetApi(Build.VERSION_CODES.N)
+ private Palette getWallpaperPalette() {
+ WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
+ if (Utilities.ATLEAST_NOUGAT) {
+ try (ParcelFileDescriptor fd = wallpaperManager
+ .getWallpaperFile(WallpaperManager.FLAG_SYSTEM)) {
+ Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
+ if (bitmap != null) {
+ return Palette.from(bitmap).clearFilters().generate();
+ }
+ } catch (IOException | NullPointerException e) {
+ Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
+ }
+ }
+
+ Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap();
+ return Palette.from(wallpaper).clearFilters().generate();
+ }
}
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index 711508ea5..e60a1bd7d 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -16,13 +16,20 @@
package com.android.launcher3.dynamicui;
+import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Color;
+import android.support.annotation.Nullable;
import android.support.v4.graphics.ColorUtils;
import android.support.v7.graphics.Palette;
import android.util.Log;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dynamicui.colorextraction.ColorExtractor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
/**
* Saves and loads colors extracted from the wallpaper, as well as the associated wallpaper id.
@@ -32,31 +39,56 @@ public class ExtractedColors {
public static final int DEFAULT_LIGHT = Color.WHITE;
public static final int DEFAULT_DARK = Color.BLACK;
- public static final int DEFAULT_COLOR = DEFAULT_LIGHT;
// These color profile indices should NOT be changed, since they are used when saving and
// loading extracted colors. New colors should always be added at the end.
public static final int VERSION_INDEX = 0;
public static final int HOTSEAT_INDEX = 1;
public static final int STATUS_BAR_INDEX = 2;
- // public static final int VIBRANT_INDEX = 2;
- // public static final int VIBRANT_DARK_INDEX = 3;
- // public static final int VIBRANT_LIGHT_INDEX = 4;
- // public static final int MUTED_INDEX = 5;
- // public static final int MUTED_DARK_INDEX = 6;
- // public static final int MUTED_LIGHT_INDEX = 7;
-
- public static final int NUM_COLOR_PROFILES = 2;
- private static final int VERSION = 1;
+ public static final int WALLPAPER_VIBRANT_INDEX = 3;
+ public static final int ALLAPPS_GRADIENT_MAIN_INDEX = 4;
+ public static final int ALLAPPS_GRADIENT_SECONDARY_INDEX = 5;
+
+ private static final int VERSION;
+ private static final int[] DEFAULT_VALUES;
+
+ static {
+ if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+ VERSION = 3;
+ DEFAULT_VALUES = new int[] {
+ VERSION, // VERSION_INDEX
+ 0x40FFFFFF, // HOTSEAT_INDEX: White with 25% alpha
+ DEFAULT_DARK, // STATUS_BAR_INDEX
+ 0xFFCCCCCC, // WALLPAPER_VIBRANT_INDEX
+ 0xFF000000, // ALLAPPS_GRADIENT_MAIN_INDEX
+ 0xFF000000 // ALLAPPS_GRADIENT_SECONDARY_INDEX
+ };
+ } else if (FeatureFlags.QSB_IN_HOTSEAT) {
+ VERSION = 2;
+ DEFAULT_VALUES = new int[] {
+ VERSION, // VERSION_INDEX
+ 0x40FFFFFF, // HOTSEAT_INDEX: White with 25% alpha
+ DEFAULT_DARK, // STATUS_BAR_INDEX
+ 0xFFCCCCCC, // WALLPAPER_VIBRANT_INDEX
+ };
+ } else {
+ VERSION = 1;
+ DEFAULT_VALUES = new int[] {
+ VERSION, // VERSION_INDEX
+ 0x40FFFFFF, // HOTSEAT_INDEX: White with 25% alpha
+ DEFAULT_DARK, // STATUS_BAR_INDEX
+ };
+ }
+ }
private static final String COLOR_SEPARATOR = ",";
- private int[] mColors;
+ private final ArrayList<OnChangeListener> mListeners = new ArrayList<>();
+ private final int[] mColors;
public ExtractedColors() {
// The first entry is reserved for the version number.
- mColors = new int[NUM_COLOR_PROFILES + 1];
- mColors[VERSION_INDEX] = VERSION;
+ mColors = Arrays.copyOf(DEFAULT_VALUES, DEFAULT_VALUES.length);
}
public void setColorAtIndex(int index, int color) {
@@ -79,17 +111,6 @@ public class ExtractedColors {
}
/**
- * Decodes a comma-separated String into {@link #mColors}.
- */
- void decodeFromString(String colorsString) {
- String[] splitColorsString = colorsString.split(COLOR_SEPARATOR);
- mColors = new int[splitColorsString.length];
- for (int i = 0; i < mColors.length; i++) {
- mColors[i] = Integer.parseInt(splitColorsString[i]);
- }
- }
-
- /**
* Loads colors and wallpaper id from {@link Utilities#getPrefs(Context)}.
* These were saved there in {@link ColorExtractionService}.
*/
@@ -97,19 +118,22 @@ public class ExtractedColors {
String encodedString = Utilities.getPrefs(context).getString(
ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, VERSION + "");
- decodeFromString(encodedString);
-
- if (mColors[VERSION_INDEX] != VERSION) {
+ String[] splitColorsString = encodedString.split(COLOR_SEPARATOR);
+ if (splitColorsString.length == DEFAULT_VALUES.length &&
+ Integer.parseInt(splitColorsString[VERSION_INDEX]) == VERSION) {
+ // Parse and apply the saved values.
+ for (int i = 0; i < mColors.length; i++) {
+ mColors[i] = Integer.parseInt(splitColorsString[i]);
+ }
+ } else {
+ // Leave the values as default values as the saved values may not be compatible.
ExtractionUtils.startColorExtractionService(context);
}
}
/** @param index must be one of the index values defined at the top of this class. */
- public int getColor(int index, int defaultColor) {
- if (index > VERSION_INDEX && index < mColors.length) {
- return mColors[index];
- }
- return defaultColor;
+ public int getColor(int index) {
+ return mColors[index];
}
/**
@@ -125,7 +149,7 @@ public class ExtractedColors {
} else if (hotseatPalette != null && ExtractionUtils.isSuperDark(hotseatPalette)) {
hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.18f * 255));
} else {
- hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.25f * 255));
+ hotseatColor = DEFAULT_VALUES[HOTSEAT_INDEX];
}
setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
}
@@ -134,4 +158,42 @@ public class ExtractedColors {
setColorAtIndex(STATUS_BAR_INDEX, ExtractionUtils.isSuperLight(statusBarPalette) ?
DEFAULT_LIGHT : DEFAULT_DARK);
}
+
+ public void updateWallpaperThemePalette(@Nullable Palette wallpaperPalette) {
+ int defaultColor = DEFAULT_VALUES[WALLPAPER_VIBRANT_INDEX];
+ setColorAtIndex(WALLPAPER_VIBRANT_INDEX, wallpaperPalette == null
+ ? defaultColor : wallpaperPalette.getVibrantColor(defaultColor));
+ }
+
+ public void updateAllAppsGradientPalette(Context context) {
+ // TODO use isAtLeastO when available
+ try {
+ WallpaperManager.class.getDeclaredMethod("getWallpaperColors", int.class);
+ ColorExtractor extractor = new ColorExtractor(context);
+ ColorExtractor.GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM);
+ setColorAtIndex(ALLAPPS_GRADIENT_MAIN_INDEX, colors.getMainColor());
+ setColorAtIndex(ALLAPPS_GRADIENT_SECONDARY_INDEX, colors.getSecondaryColor());
+ } catch (NoSuchMethodException e) {
+ setColorAtIndex(ALLAPPS_GRADIENT_MAIN_INDEX, Color.WHITE);
+ setColorAtIndex(ALLAPPS_GRADIENT_SECONDARY_INDEX, Color.WHITE);
+ }
+ }
+
+ public void addOnChangeListener(OnChangeListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void notifyChange() {
+ for (OnChangeListener listener : mListeners) {
+ listener.onExtractedColorsChanged();
+ }
+ }
+
+ /**
+ * Interface for listening for extracted color changes
+ */
+ public interface OnChangeListener {
+
+ void onExtractedColorsChanged();
+ }
}
diff --git a/src/com/android/launcher3/dynamicui/colorextraction/ColorExtractor.java b/src/com/android/launcher3/dynamicui/colorextraction/ColorExtractor.java
new file mode 100644
index 000000000..153b52914
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/colorextraction/ColorExtractor.java
@@ -0,0 +1,136 @@
+package com.android.launcher3.dynamicui.colorextraction;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.launcher3.dynamicui.colorextraction.types.ExtractionType;
+import com.android.launcher3.dynamicui.colorextraction.types.Tonal;
+
+import java.lang.reflect.Method;
+
+
+/**
+ * Class to process wallpaper colors and generate a tonal palette based on them.
+ *
+ * TODO remove this class if available by platform
+ */
+public class ColorExtractor {
+ private static final String TAG = "ColorExtractor";
+ private static final int FALLBACK_COLOR = Color.WHITE;
+
+ private int mMainFallbackColor = FALLBACK_COLOR;
+ private int mSecondaryFallbackColor = FALLBACK_COLOR;
+ private final GradientColors mSystemColors;
+ private final GradientColors mLockColors;
+ private final Context mContext;
+ private final ExtractionType mExtractionType;
+
+ public ColorExtractor(Context context) {
+ mContext = context;
+ mSystemColors = new GradientColors();
+ mLockColors = new GradientColors();
+ mExtractionType = new Tonal();
+ WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
+
+ if (wallpaperManager == null) {
+ Log.w(TAG, "Can't listen to color changes!");
+ } else {
+ Parcelable wallpaperColorsObj;
+ try {
+ Method method = WallpaperManager.class
+ .getDeclaredMethod("getWallpaperColors", int.class);
+
+ wallpaperColorsObj = (Parcelable) method.invoke(wallpaperManager,
+ WallpaperManager.FLAG_SYSTEM);
+ extractInto(new WallpaperColorsCompat(wallpaperColorsObj), mSystemColors);
+ wallpaperColorsObj = (Parcelable) method.invoke(wallpaperManager,
+ WallpaperManager.FLAG_LOCK);
+ extractInto(new WallpaperColorsCompat(wallpaperColorsObj), mLockColors);
+ } catch (Exception e) {
+ Log.e(TAG, "reflection failed", e);
+ }
+ }
+ }
+
+ public GradientColors getColors(int which) {
+ if (which == WallpaperManager.FLAG_LOCK) {
+ return mLockColors;
+ } else if (which == WallpaperManager.FLAG_SYSTEM) {
+ return mSystemColors;
+ } else {
+ throw new IllegalArgumentException("which should be either FLAG_SYSTEM or FLAG_LOCK");
+ }
+ }
+
+ private void extractInto(WallpaperColorsCompat inWallpaperColors, GradientColors outGradientColors) {
+ applyFallback(outGradientColors);
+ if (inWallpaperColors == null) {
+ return;
+ }
+ mExtractionType.extractInto(inWallpaperColors, outGradientColors);
+ }
+
+ private void applyFallback(GradientColors outGradientColors) {
+ outGradientColors.setMainColor(mMainFallbackColor);
+ outGradientColors.setSecondaryColor(mSecondaryFallbackColor);
+ }
+
+ public static class GradientColors {
+ private int mMainColor = FALLBACK_COLOR;
+ private int mSecondaryColor = FALLBACK_COLOR;
+ private boolean mSupportsDarkText;
+
+ public void setMainColor(int mainColor) {
+ mMainColor = mainColor;
+ }
+
+ public void setSecondaryColor(int secondaryColor) {
+ mSecondaryColor = secondaryColor;
+ }
+
+ public void setSupportsDarkText(boolean supportsDarkText) {
+ mSupportsDarkText = supportsDarkText;
+ }
+
+ public void set(GradientColors other) {
+ mMainColor = other.mMainColor;
+ mSecondaryColor = other.mSecondaryColor;
+ mSupportsDarkText = other.mSupportsDarkText;
+ }
+
+ public int getMainColor() {
+ return mMainColor;
+ }
+
+ public int getSecondaryColor() {
+ return mSecondaryColor;
+ }
+
+ public boolean supportsDarkText() {
+ return mSupportsDarkText;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || o.getClass() != getClass()) {
+ return false;
+ }
+ GradientColors other = (GradientColors) o;
+ return other.mMainColor == mMainColor &&
+ other.mSecondaryColor == mSecondaryColor &&
+ other.mSupportsDarkText == mSupportsDarkText;
+ }
+
+ @Override
+ public int hashCode() {
+ int code = mMainColor;
+ code = 31 * code + mSecondaryColor;
+ code = 31 * code + (mSupportsDarkText ? 0 : 1);
+ return code;
+ }
+ }
+}
+
diff --git a/src/com/android/launcher3/dynamicui/colorextraction/WallpaperColorsCompat.java b/src/com/android/launcher3/dynamicui/colorextraction/WallpaperColorsCompat.java
new file mode 100644
index 000000000..f80a675cb
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/colorextraction/WallpaperColorsCompat.java
@@ -0,0 +1,69 @@
+package com.android.launcher3.dynamicui.colorextraction;
+
+import android.graphics.Color;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Pair;
+
+import java.util.List;
+
+/**
+ * A wrapper around platform implementation of WallpaperColors until the
+ * updated SDK is available.
+ *
+ * TODO remove this class if available by platform
+ */
+public class WallpaperColorsCompat implements Parcelable {
+
+ private final Parcelable mObject;
+
+ public WallpaperColorsCompat(Parcelable object) {
+ mObject = object;
+ }
+
+ private Object invokeMethod(String methodName) {
+ try {
+ return mObject.getClass().getDeclaredMethod(methodName).invoke(mObject);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeParcelable(mObject, i);
+ }
+
+ public static final Parcelable.Creator<WallpaperColorsCompat> CREATOR =
+ new Parcelable.Creator<WallpaperColorsCompat>() {
+ public WallpaperColorsCompat createFromParcel(Parcel source) {
+ Parcelable object = source.readParcelable(null);
+ return new WallpaperColorsCompat(object);
+ }
+
+ public WallpaperColorsCompat[] newArray(int size) {
+ return new WallpaperColorsCompat[size];
+ }
+ };
+
+ public List<Pair<Color, Integer>> getColors() {
+ try {
+ return (List<Pair<Color, Integer>>) invokeMethod("getColors");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public boolean supportsDarkText() {
+ try {
+ return (Boolean) invokeMethod("supportsDarkText");
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/dynamicui/colorextraction/types/ExtractionType.java b/src/com/android/launcher3/dynamicui/colorextraction/types/ExtractionType.java
new file mode 100644
index 000000000..166c7c6f4
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/colorextraction/types/ExtractionType.java
@@ -0,0 +1,23 @@
+package com.android.launcher3.dynamicui.colorextraction.types;
+
+import com.android.launcher3.dynamicui.colorextraction.ColorExtractor;
+import com.android.launcher3.dynamicui.colorextraction.WallpaperColorsCompat;
+
+
+/**
+ * Interface to allow various color extraction implementations.
+ *
+ * TODO remove this class if available by platform
+ */
+public interface ExtractionType {
+
+ /**
+ * Executes color extraction by reading WallpaperColors and setting
+ * main and secondary colors on GradientColors.
+ *
+ * @param inWallpaperColors where to read from
+ * @param outGradientColors object that should receive the colors
+ */
+ void extractInto(WallpaperColorsCompat inWallpaperColors,
+ ColorExtractor.GradientColors outGradientColors);
+}
diff --git a/src/com/android/launcher3/dynamicui/colorextraction/types/Tonal.java b/src/com/android/launcher3/dynamicui/colorextraction/types/Tonal.java
new file mode 100644
index 000000000..1e165a382
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/colorextraction/types/Tonal.java
@@ -0,0 +1,299 @@
+package com.android.launcher3.dynamicui.colorextraction.types;
+
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.graphics.ColorUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.launcher3.dynamicui.colorextraction.ColorExtractor;
+import com.android.launcher3.dynamicui.colorextraction.WallpaperColorsCompat;
+
+import java.util.Comparator;
+
+
+/**
+ * Implementation of tonal color extraction
+ *
+ * TODO remove this class if available by platform
+ */
+public class Tonal implements ExtractionType {
+ private static final String TAG = "Tonal";
+
+ // Used for tonal palette fitting
+ private static final float FIT_WEIGHT_H = 1.0f;
+ private static final float FIT_WEIGHT_S = 1.0f;
+ private static final float FIT_WEIGHT_L = 10.0f;
+
+ private static final float MIN_COLOR_OCCURRENCE = 0.1f;
+ private static final float MIN_LUMINOSITY = 0.5f;
+
+ public void extractInto(WallpaperColorsCompat wallpaperColors,
+ ColorExtractor.GradientColors gradientColors) {
+ if (wallpaperColors.getColors().size() == 0) {
+ return;
+ }
+ // Tonal is not really a sort, it takes a color from the extracted
+ // palette and finds a best fit amongst a collection of pre-defined
+ // palettes. The best fit is tweaked to be closer to the source color
+ // and replaces the original palette
+
+ // First find the most representative color in the image
+ populationSort(wallpaperColors);
+ // Calculate total
+ int total = 0;
+ for (Pair<Color, Integer> weightedColor : wallpaperColors.getColors()) {
+ total += weightedColor.second;
+ }
+
+ // Get bright colors that occur often enough in this image
+ Pair<Color, Integer> bestColor = null;
+ float[] hsl = new float[3];
+ for (Pair<Color, Integer> weightedColor : wallpaperColors.getColors()) {
+ float colorOccurrence = weightedColor.second / (float) total;
+ if (colorOccurrence < MIN_COLOR_OCCURRENCE) {
+ break;
+ }
+
+ int colorValue = weightedColor.first.toArgb();
+ ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
+ Color.blue(colorValue), hsl);
+ if (hsl[2] > MIN_LUMINOSITY) {
+ bestColor = weightedColor;
+ }
+ }
+
+ // Fallback to first color
+ if (bestColor == null) {
+ bestColor = wallpaperColors.getColors().get(0);
+ }
+
+ int colorValue = bestColor.first.toArgb();
+ ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
+ hsl);
+ hsl[0] /= 360.0f; // normalize
+
+ // TODO, we're finding a tonal palette for a hue, not all components
+ TonalPalette palette = findTonalPalette(hsl[0]);
+
+ // Fall back to population sort if we couldn't find a tonal palette
+ if (palette == null) {
+ Log.w(TAG, "Could not find a tonal palette!");
+ return;
+ }
+
+ int fitIndex = bestFit(palette, hsl[0], hsl[1], hsl[2]);
+ if (fitIndex == -1) {
+ Log.w(TAG, "Could not find best fit!");
+ return;
+ }
+ float[] h = fit(palette.h, hsl[0], fitIndex,
+ Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
+ float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
+ float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);
+
+
+ hsl[0] = fract(h[0]) * 360.0f;
+ hsl[1] = s[0];
+ hsl[2] = l[0];
+ gradientColors.setMainColor(ColorUtils.HSLToColor(hsl));
+
+ hsl[0] = fract(h[1]) * 360.0f;
+ hsl[1] = s[1];
+ hsl[2] = l[1];
+ gradientColors.setSecondaryColor(ColorUtils.HSLToColor(hsl));
+ }
+
+ private static void populationSort(@NonNull WallpaperColorsCompat wallpaperColors) {
+ wallpaperColors.getColors().sort(new Comparator<Pair<Color, Integer>>() {
+ @Override
+ public int compare(Pair<Color, Integer> a, Pair<Color, Integer> b) {
+ return b.second - a.second;
+ }
+ });
+ }
+
+ /**
+ * Offsets all colors by a delta, clamping values that go beyond what's
+ * supported on the color space.
+ * @param data what you want to fit
+ * @param v how big should be the offset
+ * @param index which index to calculate the delta against
+ * @param min minimum accepted value (clamp)
+ * @param max maximum accepted value (clamp)
+ * @return
+ */
+ private static float[] fit(float[] data, float v, int index, float min, float max) {
+ float[] fitData = new float[data.length];
+ float delta = v - data[index];
+
+ for (int i = 0; i < data.length; i++) {
+ fitData[i] = constrain(data[i] + delta, min, max);
+ }
+
+ return fitData;
+ }
+
+ // TODO no MathUtils
+ private static float constrain(float x, float min, float max) {
+ x = Math.min(x, max);
+ x = Math.max(x, min);
+ return x;
+ }
+
+ /*function adjustSatLumForFit(val, points, fitIndex) {
+ var fitValue = lerpBetweenPoints(points, fitIndex);
+ var diff = val - fitValue;
+
+ var newPoints = [];
+ for (var ii=0; ii<points.length; ii++) {
+ var point = [points[ii][0], points[ii][1]];
+ point[1] += diff;
+ if (point[1] > 1) point[1] = 1;
+ if (point[1] < 0) point[1] = 0;
+ newPoints[ii] = point;
+ }
+ return newPoints;
+ }*/
+
+ /**
+ * Finds the closest color in a palette, given another HSL color
+ *
+ * @param palette where to search
+ * @param h hue
+ * @param s saturation
+ * @param l lightness
+ * @return closest index or -1 if palette is empty.
+ */
+ private static int bestFit(@NonNull TonalPalette palette, float h, float s, float l) {
+ int minErrorIndex = -1;
+ float minError = Float.POSITIVE_INFINITY;
+
+ for (int i = 0; i < palette.h.length; i++) {
+ float error =
+ FIT_WEIGHT_H * Math.abs(h - palette.h[i])
+ + FIT_WEIGHT_S * Math.abs(s - palette.s[i])
+ + FIT_WEIGHT_L * Math.abs(l - palette.l[i]);
+ if (error < minError) {
+ minError = error;
+ minErrorIndex = i;
+ }
+ }
+
+ return minErrorIndex;
+ }
+
+ @Nullable
+ private static TonalPalette findTonalPalette(float h) {
+ TonalPalette best = null;
+ float error = Float.POSITIVE_INFINITY;
+
+ for (TonalPalette candidate : TONAL_PALETTES) {
+ if (h >= candidate.minHue && h <= candidate.maxHue) {
+ best = candidate;
+ break;
+ }
+
+ if (candidate.maxHue > 1.0f && h >= 0.0f && h <= fract(candidate.maxHue)) {
+ best = candidate;
+ break;
+ }
+
+ if (candidate.minHue < 0.0f && h >= fract(candidate.minHue) && h <= 1.0f) {
+ best = candidate;
+ break;
+ }
+
+ if (h <= candidate.minHue && candidate.minHue - h < error) {
+ best = candidate;
+ error = candidate.minHue - h;
+ } else if (h >= candidate.maxHue && h - candidate.maxHue < error) {
+ best = candidate;
+ error = h - candidate.maxHue;
+ } else if (candidate.maxHue > 1.0f && h >= fract(candidate.maxHue)
+ && h - fract(candidate.maxHue) < error) {
+ best = candidate;
+ error = h - fract(candidate.maxHue);
+ } else if (candidate.minHue < 0.0f && h <= fract(candidate.minHue)
+ && fract(candidate.minHue) - h < error) {
+ best = candidate;
+ error = fract(candidate.minHue) - h;
+ }
+ }
+
+ return best;
+ }
+
+ private static float fract(float v) {
+ return v - (float) Math.floor(v);
+ }
+
+ static class TonalPalette {
+ final float[] h;
+ final float[] s;
+ final float[] l;
+ final float minHue;
+ final float maxHue;
+
+ TonalPalette(float[] h, float[] s, float[] l) {
+ this.h = h;
+ this.s = s;
+ this.l = l;
+
+ float minHue = Float.POSITIVE_INFINITY;
+ float maxHue = Float.NEGATIVE_INFINITY;
+
+ for (float v : h) {
+ minHue = Math.min(v, minHue);
+ maxHue = Math.max(v, maxHue);
+ }
+
+ this.minHue = minHue;
+ this.maxHue = maxHue;
+ }
+ }
+
+ // Data definition of Material Design tonal palettes
+ // When the sort type is set to TONAL, these palettes are used to find
+ // a best fist. Each palette is defined as 10 HSL colors
+ private static final TonalPalette[] TONAL_PALETTES = {
+ // Orange
+ new TonalPalette(
+ new float[] { 0.028f, 0.042f, 0.053f, 0.061f, 0.078f, 0.1f, 0.111f, 0.111f, 0.111f, 0.111f },
+ new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f },
+ new float[] { 0.5f, 0.53f, 0.54f, 0.55f, 0.535f, 0.52f, 0.5f, 0.63f, 0.75f, 0.85f }
+ ),
+ // Yellow
+ new TonalPalette(
+ new float[] { 0.111f, 0.111f, 0.125f, 0.133f, 0.139f, 0.147f, 0.156f, 0.156f, 0.156f, 0.156f },
+ new float[] { 1f, 0.942f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f },
+ new float[] { 0.43f, 0.484f, 0.535f, 0.555f, 0.57f, 0.575f, 0.595f, 0.715f, 0.78f, 0.885f }
+ ),
+ // Green
+ new TonalPalette(
+ new float[] { 0.325f, 0.336f, 0.353f, 0.353f, 0.356f, 0.356f, 0.356f, 0.356f, 0.356f, 0.356f },
+ new float[] { 1f, 1f, 0.852f, 0.754f, 0.639f, 0.667f, 0.379f, 0.542f, 1f, 1f },
+ new float[] { 0.06f, 0.1f, 0.151f, 0.194f, 0.25f, 0.312f, 0.486f, 0.651f, 0.825f, 0.885f }
+ ),
+ // Blue
+ new TonalPalette(
+ new float[] { 0.631f, 0.603f, 0.592f, 0.586f, 0.572f, 0.544f, 0.519f, 0.519f, 0.519f, 0.519f },
+ new float[] { 0.852f, 1f, 0.887f, 0.852f, 0.871f, 0.907f, 0.949f, 0.934f, 0.903f, 0.815f },
+ new float[] { 0.34f, 0.38f, 0.482f, 0.497f, 0.536f, 0.571f, 0.608f, 0.696f, 0.794f, 0.892f }
+ ),
+ // Purple
+ new TonalPalette(
+ new float[] { 0.839f, 0.831f, 0.825f, 0.819f, 0.803f, 0.803f, 0.772f, 0.772f, 0.772f, 0.772f },
+ new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 0.769f, 0.701f, 0.612f, 0.403f },
+ new float[] { 0.125f, 0.15f, 0.2f, 0.245f, 0.31f, 0.36f, 0.567f, 0.666f, 0.743f, 0.833f }
+ ),
+ // Red
+ new TonalPalette(
+ new float[] { 0.964f, 0.975f, 0.975f, 0.975f, 0.972f, 0.992f, 1.003f, 1.011f, 1.011f, 1.011f },
+ new float[] { 0.869f, 0.802f, 0.739f, 0.903f, 1f, 1f, 1f, 1f, 1f, 1f },
+ new float[] { 0.241f, 0.316f, 0.46f, 0.586f, 0.655f, 0.7f, 0.75f, 0.8f, 0.84f, 0.88f }
+ )
+ };
+}
+
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
index 840fcf5fe..0df787ac3 100644
--- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
@@ -1,12 +1,5 @@
package com.android.launcher3.folder;
-import android.view.View;
-
-import com.android.launcher3.config.FeatureFlags;
-
-import java.util.ArrayList;
-import java.util.List;
-
public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;
@@ -121,6 +114,11 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
}
@Override
+ public float getIconSize() {
+ return mIconSize;
+ }
+
+ @Override
public int maxNumItems() {
return MAX_NUM_ITEMS_IN_PREVIEW;
}
@@ -129,24 +127,4 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
public boolean clipToBackground() {
return true;
}
-
- @Override
- public List<View> getItemsToDisplay(Folder folder) {
- List<View> items = new ArrayList<>(folder.getItemsInReadingOrder());
- int numItems = items.size();
- if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION && numItems > MAX_NUM_ITEMS_IN_PREVIEW) {
- // We match the icons in the preview with the layout of the opened folder (b/27944225),
- // but we still need to figure out how we want to handle updating the preview when the
- // upper left quadrant changes.
- int appsPerRow = folder.mContent.getPageAt(0).getCountX();
- int appsToDelete = appsPerRow - MAX_NUM_ITEMS_PER_ROW;
-
- // We only display the upper left quadrant.
- while (appsToDelete > 0) {
- items.remove(MAX_NUM_ITEMS_PER_ROW);
- appsToDelete--;
- }
- }
- return items.subList(0, Math.min(numItems, MAX_NUM_ITEMS_IN_PREVIEW));
- }
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 93c9ea8e3..c6bf3a1c1 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -34,7 +34,6 @@ import android.view.FocusFinder;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.accessibility.AccessibilityEvent;
@@ -46,6 +45,7 @@ import android.widget.TextView;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Alarm;
import com.android.launcher3.AppInfo;
+import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
@@ -66,8 +66,9 @@ import com.android.launcher3.UninstallDropTarget.DropTargetSource;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
+import com.android.launcher3.anim.AnimationLayerSet;
+import com.android.launcher3.anim.CircleRevealOutlineProvider;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragLayer;
@@ -75,12 +76,12 @@ import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.CircleRevealOutlineProvider;
import com.android.launcher3.util.Thunk;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.List;
/**
* Represents a set of icons chosen by the user or generated by the system.
@@ -133,8 +134,10 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
@Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
+ private AnimatorSet mCurrentAnimator;
+
private final int mExpandDuration;
- private final int mMaterialExpandDuration;
+ public final int mMaterialExpandDuration;
private final int mMaterialExpandStagger;
protected final Launcher mLauncher;
@@ -501,51 +504,31 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
mState = STATE_SMALL;
}
- /**
- * Opens the user folder described by the specified tag. The opening of the folder
- * is animated relative to the specified View. If the View is null, no animation
- * is played.
- */
- public void animateOpen() {
- Folder openFolder = getOpen(mLauncher);
- if (openFolder != null && openFolder != this) {
- // Close any open folder before opening a folder.
- openFolder.close(true);
+ private void startAnimation(final AnimatorSet a) {
+ if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+ mCurrentAnimator.cancel();
}
-
- DragLayer dragLayer = mLauncher.getDragLayer();
- // Just verify that the folder hasn't already been added to the DragLayer.
- // There was a one-off crash where the folder had a parent already.
- if (getParent() == null) {
- dragLayer.addView(this);
- mDragController.addDropTarget(this);
- } else {
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
- Log.e(TAG, "Opening folder (" + this + ") which already has a parent:"
- + getParent());
+ a.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mState = STATE_ANIMATING;
+ mCurrentAnimator = a;
}
- }
-
- mIsOpen = true;
- mContent.completePendingPageChanges();
- if (!mDragInProgress) {
- // Open on the first page.
- mContent.snapToPageImmediately(0);
- }
-
- // This is set to true in close(), but isn't reset to false until onDropCompleted(). This
- // leads to an inconsistent state if you drag out of the folder and drag back in without
- // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
- mDeleteFolderOnDropCompleted = false;
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCurrentAnimator = null;
+ }
+ });
+ a.start();
+ }
- final Runnable onCompleteRunnable;
+ private AnimatorSet getOpeningAnimator() {
prepareReveal();
- centerAboutIcon();
-
mFolderIcon.growAndFadeOut();
AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
+
int width = getFolderWidth();
int height = getFolderHeight();
@@ -587,24 +570,76 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
anim.play(textAlpha);
anim.play(reveal);
- mContent.setLayerType(LAYER_TYPE_HARDWARE, null);
- mFooter.setLayerType(LAYER_TYPE_HARDWARE, null);
+ AnimationLayerSet layerSet = new AnimationLayerSet();
+ layerSet.addView(mContent);
+ layerSet.addView(mFooter);
+ anim.addListener(layerSet);
+
+ return anim;
+ }
+
+ /**
+ * Opens the user folder described by the specified tag. The opening of the folder
+ * is animated relative to the specified View. If the View is null, no animation
+ * is played.
+ */
+ public void animateOpen() {
+ Folder openFolder = getOpen(mLauncher);
+ if (openFolder != null && openFolder != this) {
+ // Close any open folder before opening a folder.
+ openFolder.close(true);
+ }
+
+ DragLayer dragLayer = mLauncher.getDragLayer();
+ // Just verify that the folder hasn't already been added to the DragLayer.
+ // There was a one-off crash where the folder had a parent already.
+ if (getParent() == null) {
+ dragLayer.addView(this);
+ mDragController.addDropTarget(this);
+ } else {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
+ Log.e(TAG, "Opening folder (" + this + ") which already has a parent:"
+ + getParent());
+ }
+ }
+
+ mIsOpen = true;
+
+ mContent.completePendingPageChanges();
+ if (!mDragInProgress) {
+ // Open on the first page.
+ mContent.snapToPageImmediately(0);
+ }
+
+ // This is set to true in close(), but isn't reset to false until onDropCompleted(). This
+ // leads to an inconsistent state if you drag out of the folder and drag back in without
+ // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
+ mDeleteFolderOnDropCompleted = false;
+
+ final Runnable onCompleteRunnable;
+ centerAboutIcon();
+
+ AnimatorSet anim = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
+ ? new FolderAnimationManager(this, true /* isOpening */).getAnimator()
+ : getOpeningAnimator();
onCompleteRunnable = new Runnable() {
@Override
public void run() {
- mContent.setLayerType(LAYER_TYPE_NONE, null);
- mFooter.setLayerType(LAYER_TYPE_NONE, null);
mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
}
};
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
+ if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.drawLeaveBehindIfExists();
+ mFolderIcon.setVisibility(INVISIBLE);
+ }
+
Utilities.sendCustomAccessibilityEvent(
Folder.this,
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
mContent.getAccessibilityDescription());
- mState = STATE_ANIMATING;
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -650,7 +685,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
}
mPageIndicator.stopAllAnimations();
- anim.start();
+ startAnimation(anim);
// Make sure the folder picks up the last drag move even if the finger doesn't move.
if (mDragController.isDragging()) {
@@ -689,7 +724,11 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
}
if (mFolderIcon != null) {
- mFolderIcon.shrinkAndFadeIn(animate);
+ if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ mFolderIcon.clearLeaveBehindIfExists();
+ } else {
+ mFolderIcon.shrinkAndFadeIn(animate);
+ }
}
if (!(getParent() instanceof DragLayer)) return;
@@ -706,12 +745,24 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
parent.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
+ private AnimatorSet getClosingAnimator() {
+ AnimatorSet animatorSet = LauncherAnimUtils.createAnimatorSet();
+ animatorSet.play(LauncherAnimUtils.ofViewAlphaAndScale(this, 0, 0.9f, 0.9f));
+
+ AnimationLayerSet layerSet = new AnimationLayerSet();
+ layerSet.addView(this);
+ animatorSet.addListener(layerSet);
+ animatorSet.setDuration(mExpandDuration);
+ return animatorSet;
+ }
+
private void animateClosed() {
- final ObjectAnimator oa = LauncherAnimUtils.ofViewAlphaAndScale(this, 0, 0.9f, 0.9f);
- oa.addListener(new AnimatorListenerAdapter() {
+ AnimatorSet a = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
+ ? new FolderAnimationManager(this, false /* isOpening */).getAnimator()
+ : getClosingAnimator();
+ a.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- setLayerType(LAYER_TYPE_NONE, null);
closeComplete(true);
}
@Override
@@ -720,12 +771,9 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
Folder.this,
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
getContext().getString(R.string.folder_closed));
- mState = STATE_ANIMATING;
}
});
- oa.setDuration(mExpandDuration);
- setLayerType(LAYER_TYPE_HARDWARE, null);
- oa.start();
+ startAnimation(a);
}
private void closeComplete(boolean wasAnimated) {
@@ -736,10 +784,15 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
}
mDragController.removeDropTarget(this);
clearFocus();
- if (wasAnimated) {
- mFolderIcon.requestFocus();
+ if (mFolderIcon != null) {
+ mFolderIcon.setVisibility(View.VISIBLE);
+ if (wasAnimated) {
+ mFolderIcon.mBackground.animateBackgroundStroke();
+ mFolderIcon.requestFocus();
+ }
}
+
if (mRearrangeOnClose) {
rearrangeChildren();
mRearrangeOnClose = false;
@@ -1027,6 +1080,9 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
}
public boolean isDropEnabled() {
+ if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+ return mState != STATE_ANIMATING;
+ }
return true;
}
@@ -1427,6 +1483,26 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
return mItemsInReadingOrder;
}
+ public List<BubbleTextView> getItemsOnCurrentPage() {
+ ArrayList<View> allItems = getItemsInReadingOrder();
+ int currentPage = mContent.getCurrentPage();
+ int lastPage = mContent.getPageCount() - 1;
+ int totalItemsInFolder = allItems.size();
+ int itemsPerPage = mContent.itemsPerPage();
+ int numItemsOnCurrentPage = currentPage == lastPage
+ ? totalItemsInFolder - (itemsPerPage * currentPage)
+ : itemsPerPage;
+
+ int startIndex = currentPage * itemsPerPage;
+ int endIndex = startIndex + numItemsOnCurrentPage;
+
+ List<BubbleTextView> itemsOnCurrentPage = new ArrayList<>(numItemsOnCurrentPage);
+ for (int i = startIndex; i < endIndex; ++i) {
+ itemsOnCurrentPage.add((BubbleTextView) allItems.get(i));
+ }
+ return itemsOnCurrentPage;
+ }
+
public void onFocusChange(View v, boolean hasFocus) {
if (v == mFolderName) {
if (hasFocus) {
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
new file mode 100644
index 000000000..bee0bd418
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -0,0 +1,362 @@
+/*
+ * 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.folder;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.GradientDrawable;
+import android.support.v4.graphics.ColorUtils;
+import android.util.Property;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.R;
+import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.util.Themes;
+
+import java.util.List;
+
+/**
+ * Manages the opening and closing animations for a {@link Folder}.
+ *
+ * All of the animations are done in the Folder.
+ * ie. When the user taps on the FolderIcon, we immediately hide the FolderIcon and show the Folder
+ * in its place before starting the animation.
+ */
+public class FolderAnimationManager {
+
+ private Folder mFolder;
+ private FolderPagedView mContent;
+ private GradientDrawable mFolderBackground;
+
+ private FolderIcon mFolderIcon;
+ private FolderIcon.PreviewBackground mPreviewBackground;
+
+ private Context mContext;
+ private Launcher mLauncher;
+
+ private final boolean mIsOpening;
+
+ private final int mDuration;
+ private final int mDelay;
+
+ private final TimeInterpolator mFolderInterpolator;
+ private final TimeInterpolator mLargeFolderPreviewItemInterpolator;
+
+ private final FolderIcon.PreviewItemDrawingParams mTmpParams =
+ new FolderIcon.PreviewItemDrawingParams(0, 0, 0, 0);
+
+ private static final Property<View, Float> SCALE_PROPERTY =
+ new Property<View, Float>(Float.class, "scale") {
+ @Override
+ public Float get(View view) {
+ return view.getScaleX();
+ }
+
+ @Override
+ public void set(View view, Float scale) {
+ view.setScaleX(scale);
+ view.setScaleY(scale);
+ }
+ };
+
+ private static final Property<List<BubbleTextView>, Integer> ITEMS_TEXT_COLOR_PROPERTY =
+ new Property<List<BubbleTextView>, Integer>(Integer.class, "textColor") {
+ @Override
+ public Integer get(List<BubbleTextView> items) {
+ return items.get(0).getCurrentTextColor();
+ }
+
+ @Override
+ public void set(List<BubbleTextView> items, Integer color) {
+ int size = items.size();
+
+ for (int i = 0; i < size; ++i) {
+ items.get(i).setTextColor(color);
+ }
+ }
+ };
+
+ public FolderAnimationManager(Folder folder, boolean isOpening) {
+ mFolder = folder;
+ mContent = folder.mContent;
+ mFolderBackground = (GradientDrawable) mFolder.getBackground();
+
+ mFolderIcon = folder.mFolderIcon;
+ mPreviewBackground = mFolderIcon.mBackground;
+
+ mContext = folder.getContext();
+ mLauncher = folder.mLauncher;
+
+ mIsOpening = isOpening;
+
+ mDuration = mFolder.mMaterialExpandDuration;
+ mDelay = mContext.getResources().getInteger(R.integer.config_folderDelay);
+
+ mFolderInterpolator = AnimationUtils.loadInterpolator(mContext,
+ R.interpolator.folder_interpolator);
+ mLargeFolderPreviewItemInterpolator = AnimationUtils.loadInterpolator(mContext,
+ R.interpolator.large_folder_preview_item_interpolator);
+ }
+
+
+ /**
+ * Prepares the Folder for animating between open / closed states.
+ */
+ public AnimatorSet getAnimator() {
+ final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) mFolder.getLayoutParams();
+ FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
+ final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
+
+ // Match position of the FolderIcon
+ final Rect folderIconPos = new Rect();
+ float scaleRelativeToDragLayer = mLauncher.getDragLayer()
+ .getDescendantRectRelativeToSelf(mFolderIcon, folderIconPos);
+ float initialSize = (mFolderIcon.mBackground.getRadius() * 2) * scaleRelativeToDragLayer;
+
+ // Match size/scale of icons in the preview
+ float previewScale = rule.scaleForItem(0, itemsInPreview.size());
+ float previewSize = rule.getIconSize() * previewScale;
+ float initialScale = previewSize / itemsInPreview.get(0).getIconSize()
+ * scaleRelativeToDragLayer;
+ final float finalScale = 1f;
+ float scale = mIsOpening ? initialScale : finalScale;
+ mFolder.setScaleX(scale);
+ mFolder.setScaleY(scale);
+ mFolder.setPivotX(0);
+ mFolder.setPivotY(0);
+
+ // We want to create a small X offset for the preview items, so that they follow their
+ // expected path to their final locations. ie. an icon should not move right, if it's final
+ // location is to its left. This value is arbitrarily defined.
+ int previewItemOffsetX = (int) (previewSize / 2);
+ if (Utilities.isRtl(mContext.getResources())) {
+ previewItemOffsetX = (int) (lp.width * initialScale - initialSize - previewItemOffsetX);
+ }
+
+ final int paddingOffsetX = (int) ((mFolder.getPaddingLeft() + mContent.getPaddingLeft())
+ * initialScale);
+ final int paddingOffsetY = (int) ((mFolder.getPaddingTop() + mContent.getPaddingTop())
+ * initialScale);
+
+ // Background can have a scaled radius in drag and drop mode.
+ int radiusDiff = mFolderIcon.mBackground.getScaledRadius()
+ - mFolderIcon.mBackground.getRadius();
+
+ int initialX = folderIconPos.left + mFolderIcon.mBackground.getOffsetX() - paddingOffsetX
+ - previewItemOffsetX + radiusDiff;
+ int initialY = folderIconPos.top + mFolderIcon.mBackground.getOffsetY() - paddingOffsetY
+ + radiusDiff;
+ final float xDistance = initialX - lp.x;
+ final float yDistance = initialY - lp.y;
+
+ // Set up the Folder background.
+ final int finalColor = Themes.getAttrColor(mContext, android.R.attr.colorPrimary);
+ final int initialColor =
+ ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha());
+ mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
+
+ // Initialize the Folder items' text.
+ final List<BubbleTextView> items = mFolder.getItemsOnCurrentPage();
+ final int finalTextColor = Themes.getAttrColor(mContext, android.R.attr.textColorSecondary);
+ ITEMS_TEXT_COLOR_PROPERTY.set(items, mIsOpening ? Color.TRANSPARENT
+ : finalTextColor);
+
+ // Set up the reveal animation that clips the Folder.
+ int totalOffsetX = paddingOffsetX + previewItemOffsetX;
+ Rect startRect = new Rect(
+ Math.round(totalOffsetX / initialScale),
+ Math.round(paddingOffsetY / initialScale),
+ Math.round((totalOffsetX + initialSize) / initialScale),
+ Math.round((paddingOffsetY + initialSize) / initialScale));
+ Rect endRect = new Rect(0, 0, lp.width, lp.height);
+ float initialRadius = initialSize / initialScale / 2f;
+ float finalRadius = Utilities.pxFromDp(2, mContext.getResources().getDisplayMetrics());
+
+ // Create the animators.
+ AnimatorSet a = LauncherAnimUtils.createAnimatorSet();
+
+ play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
+ play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
+ play(a, getAnimator(mFolder, SCALE_PROPERTY, initialScale, finalScale));
+ play(a, getAnimator(items, ITEMS_TEXT_COLOR_PROPERTY, Color.TRANSPARENT, finalTextColor));
+ play(a, getAnimator(mFolderBackground, "color", initialColor, finalColor));
+ play(a, new RoundedRectRevealOutlineProvider(initialRadius, finalRadius, startRect,
+ endRect).createRevealAnimator(mFolder, !mIsOpening));
+
+ a.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ ITEMS_TEXT_COLOR_PROPERTY.set(items, finalTextColor);
+ mFolder.setTranslationX(0.0f);
+ mFolder.setTranslationY(0.0f);
+ mFolder.setScaleX(1f);
+ mFolder.setScaleY(1f);
+ }
+ });
+
+ // We set the interpolator on all current child animators here, because the preview item
+ // animators may use a different interpolator.
+ for (Animator animator : a.getChildAnimations()) {
+ animator.setInterpolator(mFolderInterpolator);
+ }
+
+ addPreviewItemAnimators(a, initialScale / scaleRelativeToDragLayer, previewItemOffsetX);
+ return a;
+ }
+
+ /**
+ * Animate the items that are displayed in the preview.
+ */
+ private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale,
+ int previewItemOffsetX) {
+ FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
+ final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
+ final int numItemsInPreview = itemsInPreview.size();
+
+ TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator();
+
+ ShortcutAndWidgetContainer cwc = mContent.getPageAt(0).getShortcutsAndWidgets();
+ for (int i = 0; i < numItemsInPreview; ++i) {
+ final BubbleTextView btv = itemsInPreview.get(i);
+ CellLayout.LayoutParams btvLp = (CellLayout.LayoutParams) btv.getLayoutParams();
+
+ // Calculate the final values in the LayoutParams.
+ btvLp.isLockedToGrid = true;
+ cwc.setupLp(btv);
+
+ // Match scale of icons in the preview.
+ float previewScale = rule.scaleForItem(i, numItemsInPreview);
+ float previewSize = rule.getIconSize() * previewScale;
+ float iconScale = previewSize / itemsInPreview.get(i).getIconSize();
+
+ final float initialScale = iconScale / folderScale;
+ final float finalScale = 1f;
+ float scale = mIsOpening ? initialScale : finalScale;
+ btv.setScaleX(scale);
+ btv.setScaleY(scale);
+
+ // Match positions of the icons in the folder with their positions in the preview
+ rule.computePreviewItemDrawingParams(i, numItemsInPreview, mTmpParams);
+ // The PreviewLayoutRule assumes that the icon size takes up the entire width so we
+ // offset by the actual size.
+ int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
+
+ final int previewPosX =
+ (int) ((mTmpParams.transX - iconOffsetX + previewItemOffsetX) / folderScale);
+ final int previewPosY = (int) (mTmpParams.transY / folderScale);
+
+ final float xDistance = previewPosX - btvLp.x;
+ final float yDistance = previewPosY - btvLp.y;
+
+ Animator translationX = getAnimator(btv, View.TRANSLATION_X, xDistance, 0f);
+ translationX.setInterpolator(previewItemInterpolator);
+ play(animatorSet, translationX);
+
+ Animator translationY = getAnimator(btv, View.TRANSLATION_Y, yDistance, 0f);
+ translationY.setInterpolator(previewItemInterpolator);
+ play(animatorSet, translationY);
+
+ Animator scaleAnimator = getAnimator(btv, SCALE_PROPERTY, initialScale, finalScale);
+ scaleAnimator.setInterpolator(previewItemInterpolator);
+ play(animatorSet, scaleAnimator);
+
+ if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+ // These delays allows the preview items to move as part of the Folder's motion,
+ // and its only necessary for large folders because of differing interpolators.
+ if (mIsOpening) {
+ translationX.setStartDelay(mDelay);
+ translationY.setStartDelay(mDelay);
+ scaleAnimator.setStartDelay(mDelay);
+ }
+ translationX.setDuration(translationX.getDuration() - mDelay);
+ translationY.setDuration(translationY.getDuration() - mDelay);
+ scaleAnimator.setDuration(scaleAnimator.getDuration() - mDelay);
+ }
+
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ // Necessary to initialize values here because of the start delay.
+ if (mIsOpening) {
+ btv.setTranslationX(xDistance);
+ btv.setTranslationY(yDistance);
+ btv.setScaleX(initialScale);
+ btv.setScaleY(initialScale);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ btv.setTranslationX(0.0f);
+ btv.setTranslationY(0.0f);
+ btv.setScaleX(1f);
+ btv.setScaleY(1f);
+ }
+ });
+ }
+ }
+
+ private void play(AnimatorSet as, Animator a) {
+ a.setDuration(mDuration);
+ as.play(a);
+ }
+
+ private TimeInterpolator getPreviewItemInterpolator() {
+ if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+ // With larger folders, we want the preview items to reach their final positions faster
+ // (when opening) and later (when closing) so that they appear aligned with the rest of
+ // the folder items when they are both visible.
+ return mLargeFolderPreviewItemInterpolator;
+ }
+ return mFolderInterpolator;
+ }
+
+ private Animator getAnimator(View view, Property property, float v1, float v2) {
+ return mIsOpening
+ ? ObjectAnimator.ofFloat(view, property, v1, v2)
+ : ObjectAnimator.ofFloat(view, property, v2, v1);
+ }
+
+ private Animator getAnimator(List<BubbleTextView> items, Property property, int v1, int v2) {
+ return mIsOpening
+ ? ObjectAnimator.ofArgb(items, property, v1, v2)
+ : ObjectAnimator.ofArgb(items, property, v2, v1);
+ }
+
+ private Animator getAnimator(GradientDrawable drawable, String property, int v1, int v2) {
+ return mIsOpening
+ ? ObjectAnimator.ofArgb(drawable, property, v1, v2)
+ : ObjectAnimator.ofArgb(drawable, property, v2, v1);
+ }
+}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 25123fb1d..6e3db0b2d 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -126,6 +126,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private float mSlop;
+ FolderIconPreviewVerifier mPreviewVerifier;
private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<PreviewItemDrawingParams>();
private Drawable mReferenceDrawable = null;
@@ -181,7 +182,8 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
DeviceProfile grid = launcher.getDeviceProfile();
- FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
+ FolderIcon icon = (FolderIcon) LayoutInflater.from(group.getContext())
+ .inflate(resId, group, false);
icon.setClipToPadding(false);
icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name);
@@ -221,6 +223,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private void setFolder(Folder folder) {
mFolder = folder;
+ mPreviewVerifier = new FolderIconPreviewVerifier(mLauncher.getDeviceProfile().inv);
updateItemDrawingParams(false);
}
@@ -407,6 +410,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
mBadgeInfo = badgeInfo;
}
+ public PreviewLayoutRule getLayoutRule() {
+ return mPreviewLayoutRule;
+ }
+
/**
* Sets mBadgeScale to 1 or 0, animating if wasBadged or isBadged is false
* (the badge is being added or removed).
@@ -540,6 +547,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private float mScale = 1f;
private float mColorMultiplier = 1f;
private float mStrokeWidth;
+ private int mStrokeAlpha = MAX_BG_OPACITY;
private View mInvalidateDelegate;
public int previewSize;
@@ -565,6 +573,21 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private static final int SHADOW_OPACITY = 40;
ValueAnimator mScaleAnimator;
+ ObjectAnimator mStrokeAlphaAnimator;
+
+ private static final Property<PreviewBackground, Integer> STROKE_ALPHA =
+ new Property<PreviewBackground, Integer>(Integer.class, "strokeAlpha") {
+ @Override
+ public Integer get(PreviewBackground previewBackground) {
+ return previewBackground.mStrokeAlpha;
+ }
+
+ @Override
+ public void set(PreviewBackground previewBackground, Integer alpha) {
+ previewBackground.mStrokeAlpha = alpha;
+ previewBackground.invalidate();
+ }
+ };
public void setup(DisplayMetrics dm, DeviceProfile grid, View invalidateDelegate,
int availableSpace, int topPadding) {
@@ -674,8 +697,24 @@ public class FolderIcon extends FrameLayout implements FolderListener {
canvas.restoreToCount(saveCount);
}
+ public void animateBackgroundStroke() {
+ if (mStrokeAlphaAnimator != null) {
+ mStrokeAlphaAnimator.cancel();
+ }
+ mStrokeAlphaAnimator = ObjectAnimator
+ .ofArgb(this, STROKE_ALPHA, MAX_BG_OPACITY / 2, MAX_BG_OPACITY)
+ .setDuration(100);
+ mStrokeAlphaAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStrokeAlphaAnimator = null;
+ }
+ });
+ mStrokeAlphaAnimator.start();
+ }
+
public void drawBackgroundStroke(Canvas canvas) {
- mPaint.setColor(Color.argb(255, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+ mPaint.setColor(Color.argb(mStrokeAlpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);
drawCircle(canvas, 1 /* deltaRadius */);
@@ -822,6 +861,14 @@ public class FolderIcon extends FrameLayout implements FolderListener {
};
animateScale(1f, 1f, onStart, onEnd);
}
+
+ public int getBackgroundAlpha() {
+ return (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
+ }
+
+ public float getStrokeWidth() {
+ return mStrokeWidth;
+ }
}
public void setFolderBackground(PreviewBackground bg) {
@@ -991,8 +1038,26 @@ public class FolderIcon extends FrameLayout implements FolderListener {
return mFolderName.getVisibility() == VISIBLE;
}
+ public List<BubbleTextView> getItemsToDisplay() {
+ mPreviewVerifier.setFolderInfo(mFolder.getInfo());
+
+ List<BubbleTextView> itemsToDisplay = new ArrayList<>();
+ List<View> allItems = mFolder.getItemsInReadingOrder();
+ int numItems = allItems.size();
+ for (int rank = 0; rank < numItems; ++rank) {
+ if (mPreviewVerifier.isItemInPreview(rank)) {
+ itemsToDisplay.add((BubbleTextView) allItems.get(rank));
+ }
+
+ if (itemsToDisplay.size() == FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+ break;
+ }
+ }
+ return itemsToDisplay;
+ }
+
private void updateItemDrawingParams(boolean animate) {
- List<View> items = mPreviewLayoutRule.getItemsToDisplay(mFolder);
+ List<BubbleTextView> items = getItemsToDisplay();
int nItemsInPreview = items.size();
int prevNumItems = mDrawingParams.size();
@@ -1007,7 +1072,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
for (int i = 0; i < mDrawingParams.size(); i++) {
PreviewItemDrawingParams p = mDrawingParams.get(i);
- p.drawable = ((TextView) items.get(i)).getCompoundDrawables()[1];
+ p.drawable = items.get(i).getCompoundDrawables()[1];
if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) {
computePreviewItemDrawingParams(i, nItemsInPreview, p);
@@ -1109,28 +1174,21 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
public void shrinkAndFadeIn(boolean animate) {
- final CellLayout cl = (CellLayout) getParent().getParent();
- ((CellLayout.LayoutParams) getLayoutParams()).canReorder = true;
-
// We remove and re-draw the FolderIcon in-case it has changed
final PreviewImageView previewImage = PreviewImageView.get(getContext());
previewImage.removeFromParent();
copyToPreview(previewImage);
- if (cl != null) {
- cl.clearFolderLeaveBehind();
- }
+ clearLeaveBehindIfExists();
ObjectAnimator oa = LauncherAnimUtils.ofViewAlphaAndScale(previewImage, 1, 1, 1);
oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));
oa.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (cl != null) {
- // Remove the ImageView copy of the FolderIcon and make the original visible.
- previewImage.removeFromParent();
- setVisibility(View.VISIBLE);
- }
+ // Remove the ImageView copy of the FolderIcon and make the original visible.
+ previewImage.removeFromParent();
+ setVisibility(View.VISIBLE);
}
});
oa.start();
@@ -1139,7 +1197,15 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
}
- public void growAndFadeOut() {
+ public void clearLeaveBehindIfExists() {
+ ((CellLayout.LayoutParams) getLayoutParams()).canReorder = true;
+ if (mInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+ CellLayout cl = (CellLayout) getParent().getParent();
+ cl.clearFolderLeaveBehind();
+ }
+ }
+
+ public void drawLeaveBehindIfExists() {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
// While the folder is open, the position of the icon cannot change.
lp.canReorder = false;
@@ -1147,6 +1213,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
CellLayout cl = (CellLayout) getParent().getParent();
cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);
}
+ }
+
+ public void growAndFadeOut() {
+ drawLeaveBehindIfExists();
// Push an ImageView copy of the FolderIcon into the DragLayer and hide the original
PreviewImageView previewImage = PreviewImageView.get(getContext());
@@ -1176,8 +1246,8 @@ public class FolderIcon extends FrameLayout implements FolderListener {
PreviewItemDrawingParams params);
void init(int availableSpace, int intrinsicIconSize, boolean rtl);
float scaleForItem(int index, int totalNumItems);
+ float getIconSize();
int maxNumItems();
boolean clipToBackground();
- List<View> getItemsToDisplay(Folder folder);
}
}
diff --git a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java
new file mode 100644
index 000000000..de962b021
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.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.folder;
+
+import com.android.launcher3.FolderInfo;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.config.FeatureFlags;
+
+/**
+ * Verifies whether an item in a Folder is displayed in the FolderIcon preview.
+ */
+public class FolderIconPreviewVerifier {
+
+ private final int mMaxGridCountX;
+ private final int mMaxGridCountY;
+ private final int mMaxItemsPerPage;
+ private final int[] mGridSize = new int[2];
+
+ private int mGridCountX;
+ private boolean mDisplayingUpperLeftQuadrant = false;
+
+ public FolderIconPreviewVerifier(InvariantDeviceProfile profile) {
+ mMaxGridCountX = profile.numFolderColumns;
+ mMaxGridCountY = profile.numFolderRows;
+ mMaxItemsPerPage = mMaxGridCountX * mMaxGridCountY;
+ }
+
+ public void setFolderInfo(FolderInfo info) {
+ int numItemsInFolder = info.contents.size();
+ mDisplayingUpperLeftQuadrant = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
+ && !FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON
+ && numItemsInFolder > FolderIcon.NUM_ITEMS_IN_PREVIEW;
+
+ if (mDisplayingUpperLeftQuadrant) {
+ FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
+ mMaxGridCountY, mMaxItemsPerPage, mGridSize);
+ mGridCountX = mGridSize[0];
+ }
+ }
+
+ public boolean isItemInPreview(int rank) {
+ if (mDisplayingUpperLeftQuadrant) {
+ // Returns true iff the icon is in the 2x2 upper left quadrant of the Folder.
+ int col = rank % mGridCountX;
+ int row = rank / mGridCountX;
+ return col < 2 && row < 2;
+ }
+ return rank < FolderIcon.NUM_ITEMS_IN_PREVIEW;
+ }
+}
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index eecce183a..2a6007a4e 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -35,17 +35,14 @@ import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace.ItemOperator;
-import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.pageindicators.PageIndicator;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import java.util.ArrayList;
@@ -68,7 +65,7 @@ public class FolderPagedView extends PagedView {
*/
private static final float SCROLL_HINT_FRACTION = 0.07f;
- private static final int[] sTempPosArray = new int[2];
+ private static final int[] sTmpArray = new int[2];
public final boolean mIsRtl;
@@ -108,7 +105,6 @@ public class FolderPagedView extends PagedView {
mIsRtl = Utilities.isRtl(getResources());
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
- setEdgeGlowColor(Themes.getAttrColor(context, android.R.attr.colorEdgeEffect));
mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
}
@@ -120,40 +116,58 @@ public class FolderPagedView extends PagedView {
}
/**
- * Sets up the grid size such that {@param count} items can fit in the grid.
+ * Calculates the grid size such that {@param count} items can fit in the grid.
* The grid size is calculated such that countY <= countX and countX = ceil(sqrt(count)) while
* maintaining the restrictions of {@link #mMaxCountX} &amp; {@link #mMaxCountY}.
*/
- private void setupContentDimensions(int count) {
- mAllocatedContentSize = count;
+ public static void calculateGridSize(int count, int countX, int countY, int maxCountX,
+ int maxCountY, int maxItemsPerPage, int[] out) {
boolean done;
- if (count >= mMaxItemsPerPage) {
- mGridCountX = mMaxCountX;
- mGridCountY = mMaxCountY;
+ int gridCountX = countX;
+ int gridCountY = countY;
+
+ if (count >= maxItemsPerPage) {
+ gridCountX = maxCountX;
+ gridCountY = maxCountY;
done = true;
} else {
done = false;
}
while (!done) {
- int oldCountX = mGridCountX;
- int oldCountY = mGridCountY;
- if (mGridCountX * mGridCountY < count) {
+ int oldCountX = gridCountX;
+ int oldCountY = gridCountY;
+ if (gridCountX * gridCountY < count) {
// Current grid is too small, expand it
- if ((mGridCountX <= mGridCountY || mGridCountY == mMaxCountY) && mGridCountX < mMaxCountX) {
- mGridCountX++;
- } else if (mGridCountY < mMaxCountY) {
- mGridCountY++;
+ if ((gridCountX <= gridCountY || gridCountY == maxCountY)
+ && gridCountX < maxCountX) {
+ gridCountX++;
+ } else if (gridCountY < maxCountY) {
+ gridCountY++;
}
- if (mGridCountY == 0) mGridCountY++;
- } else if ((mGridCountY - 1) * mGridCountX >= count && mGridCountY >= mGridCountX) {
- mGridCountY = Math.max(0, mGridCountY - 1);
- } else if ((mGridCountX - 1) * mGridCountY >= count) {
- mGridCountX = Math.max(0, mGridCountX - 1);
+ if (gridCountY == 0) gridCountY++;
+ } else if ((gridCountY - 1) * gridCountX >= count && gridCountY >= gridCountX) {
+ gridCountY = Math.max(0, gridCountY - 1);
+ } else if ((gridCountX - 1) * gridCountY >= count) {
+ gridCountX = Math.max(0, gridCountX - 1);
}
- done = mGridCountX == oldCountX && mGridCountY == oldCountY;
+ done = gridCountX == oldCountX && gridCountY == oldCountY;
}
+ out[0] = gridCountX;
+ out[1] = gridCountY;
+ }
+
+ /**
+ * Sets up the grid size such that {@param count} items can fit in the grid.
+ */
+ public void setupContentDimensions(int count) {
+ mAllocatedContentSize = count;
+ calculateGridSize(count, mGridCountX, mGridCountY, mMaxCountX, mMaxCountY, mMaxItemsPerPage,
+ sTmpArray);
+ mGridCountX = sTmpArray[0];
+ mGridCountY = sTmpArray[1];
+
// Update grid size
for (int i = getPageCount() - 1; i >= 0; i--) {
getPageAt(i).setGridSize(mGridCountX, mGridCountY);
@@ -314,6 +328,8 @@ public class FolderPagedView extends PagedView {
int position = 0;
int newX, newY, rank;
+ FolderIconPreviewVerifier verifier = new FolderIconPreviewVerifier(
+ Launcher.getLauncher(getContext()).getDeviceProfile().inv);
rank = 0;
for (int i = 0; i < itemCount; i++) {
View v = list.size() > i ? list.get(i) : null;
@@ -346,7 +362,7 @@ public class FolderPagedView extends PagedView {
currentPage.addViewToCellLayout(
v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
- if (rank < FolderIcon.NUM_ITEMS_IN_PREVIEW && v instanceof BubbleTextView) {
+ if (verifier.isItemInPreview(rank) && v instanceof BubbleTextView) {
((BubbleTextView) v).verifyHighRes();
}
}
@@ -400,12 +416,12 @@ public class FolderPagedView extends PagedView {
public int findNearestArea(int pixelX, int pixelY) {
int pageIndex = getNextPage();
CellLayout page = getPageAt(pageIndex);
- page.findNearestArea(pixelX, pixelY, 1, 1, sTempPosArray);
+ page.findNearestArea(pixelX, pixelY, 1, 1, sTmpArray);
if (mFolder.isLayoutRtl()) {
- sTempPosArray[0] = page.getCountX() - sTempPosArray[0] - 1;
+ sTmpArray[0] = page.getCountX() - sTmpArray[0] - 1;
}
return Math.min(mAllocatedContentSize - 1,
- pageIndex * mMaxItemsPerPage + sTempPosArray[1] * mGridCountX + sTempPosArray[0]);
+ pageIndex * mMaxItemsPerPage + sTmpArray[1] * mGridCountX + sTmpArray[0]);
}
public boolean isFull() {
diff --git a/src/com/android/launcher3/folder/PreviewImageView.java b/src/com/android/launcher3/folder/PreviewImageView.java
index c4f3ee15c..65d9db118 100644
--- a/src/com/android/launcher3/folder/PreviewImageView.java
+++ b/src/com/android/launcher3/folder/PreviewImageView.java
@@ -22,7 +22,6 @@ import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.ImageView;
import com.android.launcher3.Launcher;
diff --git a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
index 297203ae2..12bca5fdf 100644
--- a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
@@ -16,12 +16,8 @@
package com.android.launcher3.folder;
-import android.view.View;
-
import com.android.launcher3.folder.FolderIcon.PreviewItemDrawingParams;
-import java.util.List;
-
public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
static final int MAX_NUM_ITEMS_IN_PREVIEW = 3;
@@ -87,6 +83,11 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
}
@Override
+ public float getIconSize() {
+ return mBaselineIconSize;
+ }
+
+ @Override
public float scaleForItem(int index, int numItems) {
// Scale is determined by the position of the icon in the preview.
index = MAX_NUM_ITEMS_IN_PREVIEW - index - 1;
@@ -98,10 +99,4 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
public boolean clipToBackground() {
return false;
}
-
- @Override
- public List<View> getItemsToDisplay(Folder folder) {
- List<View> items = folder.getItemsInReadingOrder();
- return items.subList(0, Math.min(items.size(), MAX_NUM_ITEMS_IN_PREVIEW));
- }
}
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index bb136f7a3..492d85373 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -29,7 +29,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetHostView;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
/**
@@ -138,7 +138,7 @@ public class DragPreviewProvider {
}
public final void generateDragOutline(Canvas canvas) {
- if (ProviderConfig.IS_DOGFOOD_BUILD && generatedDragOutline != null) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && generatedDragOutline != null) {
throw new RuntimeException("Drag outline generated twice");
}
diff --git a/src/com/android/launcher3/graphics/GradientView.java b/src/com/android/launcher3/graphics/GradientView.java
new file mode 100644
index 000000000..c5b769366
--- /dev/null
+++ b/src/com/android/launcher3/graphics/GradientView.java
@@ -0,0 +1,140 @@
+/*
+ * 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.graphics;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+/**
+ * Draws a translucent radial gradient background from an initial state with progress 0.0 to a
+ * final state with progress 1.0;
+ */
+public class GradientView extends View {
+
+ private static final int DEFAULT_COLOR = Color.WHITE;
+ private static final float GRADIENT_ALPHA_MASK_LENGTH_DP = 300;
+ private static final float FINAL_GRADIENT_ALPHA = 0.75f;
+ private static final boolean DEBUG = false;
+
+ private static Bitmap sFinalGradientMask;
+ private static Bitmap sAlphaGradientMask;
+
+ private int mColor1 = DEFAULT_COLOR;
+ private int mColor2 = DEFAULT_COLOR;
+ private int mWidth;
+ private int mHeight;
+ private final RectF mAlphaMaskRect = new RectF();
+ private final RectF mFinalMaskRect = new RectF();
+ private final Paint mPaint = new Paint();
+ private float mProgress;
+ private final int mMaskHeight;
+ private final Context mAppContext;
+ private final Paint mDebugPaint = DEBUG ? new Paint() : null;
+ private final Interpolator mAccelerator = new AccelerateInterpolator();
+
+ public GradientView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ this.mAppContext = context.getApplicationContext();
+ this.mMaskHeight = Utilities.pxFromDp(GRADIENT_ALPHA_MASK_LENGTH_DP,
+ mAppContext.getResources().getDisplayMetrics());
+
+ if (sFinalGradientMask == null) {
+ sFinalGradientMask = Utilities.convertToAlphaMask(
+ Utilities.createOnePixBitmap(), FINAL_GRADIENT_ALPHA);
+ }
+ if (sAlphaGradientMask == null) {
+ Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(context.getResources(),
+ R.drawable.all_apps_alpha_mask);
+ sAlphaGradientMask = Utilities.convertToAlphaMask(
+ alphaMaskFromResource, FINAL_GRADIENT_ALPHA);
+ }
+ }
+
+ public void onExtractedColorsChanged(int color1, int color2) {
+ this.mColor1 = color1;
+ this.mColor2 = color2;
+ if (mWidth + mHeight > 0) {
+ createRadialShader();
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ this.mWidth = getMeasuredWidth();
+ this.mHeight = getMeasuredHeight();
+ if (mWidth + mHeight > 0) {
+ createRadialShader();
+ }
+ }
+
+ // only being called when colors change
+ private void createRadialShader() {
+ final float gradientCenterY = 1.05f;
+ float radius = Math.max(mHeight, mWidth) * gradientCenterY;
+
+ float posScreenBottom = (radius - mHeight) / radius; // center lives below screen
+ RadialGradient shader = new RadialGradient(
+ mWidth * 0.5f,
+ mHeight * gradientCenterY,
+ radius,
+ new int[] {mColor1, mColor1, mColor2},
+ new float[] {0f, posScreenBottom, 1f},
+ Shader.TileMode.CLAMP);
+ mPaint.setShader(shader);
+ }
+
+ public void setProgress(float progress) {
+ this.mProgress = progress;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ float head = 0.29f;
+ float linearProgress = head + (mProgress * (1f - head));
+ float startMaskY = (1f - linearProgress) * mHeight - mMaskHeight * linearProgress;
+ float startAlpha = 100;
+ float interpolatedAlpha = (255 - startAlpha) * mAccelerator.getInterpolation(mProgress);
+ mPaint.setAlpha((int) (startAlpha + interpolatedAlpha));
+ mAlphaMaskRect.set(0, startMaskY, mWidth, startMaskY + mMaskHeight);
+ mFinalMaskRect.set(0, startMaskY + mMaskHeight, mWidth, mHeight);
+ canvas.drawBitmap(sAlphaGradientMask, null, mAlphaMaskRect, mPaint);
+ canvas.drawBitmap(sFinalGradientMask, null, mFinalMaskRect, mPaint);
+
+ if (DEBUG) {
+ mDebugPaint.setColor(0xFF00FF00);
+ canvas.drawLine(0, startMaskY, mWidth, startMaskY, mDebugPaint);
+ canvas.drawLine(0, startMaskY + mMaskHeight, mWidth, startMaskY + mMaskHeight, mDebugPaint);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
index c9873d9ea..b22182883 100644
--- a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
+++ b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
@@ -31,7 +31,7 @@ import android.util.SparseArray;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import java.nio.ByteBuffer;
@@ -86,7 +86,7 @@ public class HolographicOutlineHelper {
* bitmap.
*/
public void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas) {
- if (ProviderConfig.IS_DOGFOOD_BUILD && srcDst.getConfig() != Bitmap.Config.ALPHA_8) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && srcDst.getConfig() != Bitmap.Config.ALPHA_8) {
throw new RuntimeException("Outline blue is only supported on alpha bitmaps");
}
diff --git a/src/com/android/launcher3/graphics/IconShapeOverride.java b/src/com/android/launcher3/graphics/IconShapeOverride.java
index 6e4d36642..a0727fb4b 100644
--- a/src/com/android/launcher3/graphics/IconShapeOverride.java
+++ b/src/com/android/launcher3/graphics/IconShapeOverride.java
@@ -38,7 +38,7 @@ import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
import java.lang.reflect.Field;
@@ -169,7 +169,7 @@ public class IconShapeOverride {
mContext.getString(R.string.icon_shape_override_progress),
true /* indeterminate */,
false /* cancelable */);
- new LooperExecuter(LauncherModel.getWorkerLooper()).execute(
+ new LooperExecutor(LauncherModel.getWorkerLooper()).execute(
new OverrideApplyHandler(mContext, newValue));
}
return false;
diff --git a/src/com/android/launcher3/graphics/ScrimView.java b/src/com/android/launcher3/graphics/ScrimView.java
new file mode 100644
index 000000000..feb3f030f
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ScrimView.java
@@ -0,0 +1,114 @@
+/*
+ * 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.graphics;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.support.v4.graphics.ColorUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+public class ScrimView extends View {
+
+ private static final boolean DEBUG = false;
+
+ private static final int MASK_HEIGHT_DP = 300;
+ private static final float MASK_START_LENGTH_FACTOR = 1f;
+ private static final float FINAL_ALPHA = 0.87f;
+ private static final int SCRIM_COLOR = ColorUtils.setAlphaComponent(
+ Color.WHITE, (int) (FINAL_ALPHA * 255));
+ private static final boolean APPLY_ALPHA = true;
+
+ private static Bitmap sFinalScrimMask;
+ private static Bitmap sAlphaScrimMask;
+
+ private final int mMaskHeight;
+ private int mVisibleHeight;
+ private final int mHeadStart;
+
+ private final RectF mAlphaMaskRect = new RectF();
+ private final RectF mFinalMaskRect = new RectF();
+ private final Paint mPaint = new Paint();
+ private float mProgress;
+ private final Interpolator mAccelerator = new AccelerateInterpolator();
+ private final Paint mDebugPaint = DEBUG ? new Paint() : null;
+
+ public ScrimView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mMaskHeight = Utilities.pxFromDp(MASK_HEIGHT_DP, getResources().getDisplayMetrics());
+ mHeadStart = (int) (mMaskHeight * MASK_START_LENGTH_FACTOR);
+ mPaint.setColor(SCRIM_COLOR);
+
+ if (sFinalScrimMask == null) {
+ sFinalScrimMask = Utilities.convertToAlphaMask(
+ Utilities.createOnePixBitmap(), FINAL_ALPHA);
+ }
+ if (sAlphaScrimMask == null) {
+ Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(getResources(),
+ R.drawable.all_apps_alpha_mask);
+ sAlphaScrimMask = Utilities.convertToAlphaMask(alphaMaskFromResource, FINAL_ALPHA);
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ mVisibleHeight = MeasureSpec.getSize(heightMeasureSpec);
+ setMeasuredDimension(width, mVisibleHeight * 2);
+ setProgress(mProgress);
+ }
+
+ public void setProgress(float progress) {
+ mProgress = progress;
+ float initialY = mVisibleHeight - mHeadStart;
+ float fullTranslationY = mVisibleHeight;
+ float linTranslationY = initialY - progress * fullTranslationY;
+ setTranslationY(linTranslationY);
+
+ if (APPLY_ALPHA) {
+ int alpha = 55 + (int) (200f * mAccelerator.getInterpolation(progress));
+ mPaint.setAlpha(alpha);
+ invalidate();
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ mAlphaMaskRect.set(0, 0, getWidth(), mMaskHeight);
+ mFinalMaskRect.set(0, mMaskHeight, getWidth(), getHeight());
+ canvas.drawBitmap(sAlphaScrimMask, null, mAlphaMaskRect, mPaint);
+ canvas.drawBitmap(sFinalScrimMask, null, mFinalMaskRect, mPaint);
+
+ if (DEBUG) {
+ mDebugPaint.setColor(0xFF0000FF);
+ canvas.drawLine(0, mAlphaMaskRect.top, getWidth(), mAlphaMaskRect.top, mDebugPaint);
+ canvas.drawLine(0, mAlphaMaskRect.bottom, getWidth(), mAlphaMaskRect.bottom, mDebugPaint);
+ }
+ }
+
+}
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
new file mode 100644
index 000000000..5e76649ca
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ShadowDrawable.java
@@ -0,0 +1,191 @@
+/*
+ * 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.graphics;
+
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * A drawable which adds shadow around a child drawable.
+ */
+public class ShadowDrawable extends Drawable {
+
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+
+ private final ShadowDrawableState mState;
+
+ public ShadowDrawable() {
+ this(new ShadowDrawableState());
+ }
+
+ private ShadowDrawable(ShadowDrawableState state) {
+ mState = state;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ Rect bounds = getBounds();
+ if (bounds.isEmpty()) {
+ return;
+ }
+ if (mState.mLastDrawnBitmap == null) {
+ regenerateBitmapCache();
+ }
+ canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mPaint.setAlpha(alpha);
+ invalidateSelf();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mPaint.setColorFilter(colorFilter);
+ invalidateSelf();
+ }
+
+ @Override
+ public ConstantState getConstantState() {
+ return mState;
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mState.mIntrinsicHeight;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mState.mIntrinsicWidth;
+ }
+
+ /**
+ * Sets the color for the generated shadow
+ */
+ public void setShadowColor(int color) {
+ if (mState.mShadowColor != color) {
+ mState.mShadowColor = color;
+ mState.mLastDrawnBitmap = null;
+ invalidateSelf();
+ }
+ }
+
+ private void regenerateBitmapCache() {
+ Bitmap bitmap = Bitmap.createBitmap(mState.mIntrinsicWidth, mState.mIntrinsicHeight,
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+
+ // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
+ Drawable d = mState.mChildState.newDrawable().mutate();
+ d.setBounds(mState.mShadowSize, mState.mShadowSize,
+ mState.mIntrinsicWidth - mState.mShadowSize,
+ mState.mIntrinsicHeight - mState.mShadowSize);
+ d.draw(canvas);
+
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL));
+ int[] offset = new int[2];
+ Bitmap shadow = bitmap.extractAlpha(paint, offset);
+
+ paint.setMaskFilter(null);
+ paint.setColor(mState.mShadowColor);
+ bitmap.eraseColor(Color.TRANSPARENT);
+ canvas.drawBitmap(shadow, offset[0], offset[1], paint);
+ d.draw(canvas);
+
+ if (Utilities.isAtLeastO()) {
+ bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+ }
+ mState.mLastDrawnBitmap = bitmap;
+ }
+
+ @Override
+ public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs,
+ Resources.Theme theme) throws XmlPullParserException, IOException {
+ super.inflate(r, parser, attrs, theme);
+
+ final TypedArray a = theme == null
+ ? r.obtainAttributes(attrs, R.styleable.ShadowDrawable)
+ : theme.obtainStyledAttributes(attrs, R.styleable.ShadowDrawable, 0, 0);
+
+ try {
+ Drawable d = a.getDrawable(R.styleable.ShadowDrawable_android_src);
+ if (d == null) {
+ throw new XmlPullParserException("missing src attribute");
+ }
+ mState.mShadowColor = a.getColor(
+ R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK);
+ mState.mShadowSize = r.getDimensionPixelSize(R.dimen.drawable_shadow_size);
+
+ mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize;
+ mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize;
+ mState.mChangingConfigurations = d.getChangingConfigurations();
+
+ mState.mChildState = d.getConstantState();
+ } finally {
+ a.recycle();
+ }
+ }
+
+ private static class ShadowDrawableState extends ConstantState {
+
+ int mChangingConfigurations;
+ int mIntrinsicWidth;
+ int mIntrinsicHeight;
+
+ int mShadowColor;
+ int mShadowSize;
+
+ Bitmap mLastDrawnBitmap;
+ ConstantState mChildState;
+
+ @Override
+ public Drawable newDrawable() {
+ return new ShadowDrawable(this);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java
index 469fe34e9..695015dcb 100644
--- a/src/com/android/launcher3/graphics/ShadowGenerator.java
+++ b/src/com/android/launcher3/graphics/ShadowGenerator.java
@@ -22,8 +22,10 @@ import android.graphics.Bitmap.Config;
import android.graphics.BlurMaskFilter;
import android.graphics.BlurMaskFilter.Blur;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
+import android.support.v4.graphics.ColorUtils;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.util.Preconditions;
@@ -39,9 +41,9 @@ public class ShadowGenerator {
// Percent of actual icon size
private static final float KEY_SHADOW_DISTANCE = 1f/48;
- public static final int KEY_SHADOW_ALPHA = 61;
+ private static final int KEY_SHADOW_ALPHA = 61;
- public static final int AMBIENT_SHADOW_ALPHA = 30;
+ private static final int AMBIENT_SHADOW_ALPHA = 30;
private static final Object LOCK = new Object();
// Singleton object guarded by {@link #LOCK}
@@ -84,43 +86,43 @@ public class ShadowGenerator {
}
public static Bitmap createPillWithShadow(int rectColor, int width, int height) {
-
float shadowRadius = height * 1f / 32;
float shadowYOffset = height * 1f / 16;
+ return createPillWithShadow(rectColor, width, height, shadowRadius, shadowYOffset,
+ new RectF());
+ }
+ public static Bitmap createPillWithShadow(int rectColor, int width, int height,
+ float shadowRadius, float shadowYOffset, RectF outRect) {
int radius = height / 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 centerX = Math.round(width / 2 + shadowRadius);
int centerY = Math.round(radius + shadowRadius + shadowYOffset);
int center = Math.max(centerX, centerY);
int size = center * 2;
Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888);
- canvas.setBitmap(result);
- int left = center - width / 2;
- int top = center - height / 2;
- int right = center + width / 2;
- int bottom = center + height / 2;
+ outRect.set(0, 0, width, height);
+ outRect.offsetTo(center - width / 2, center - height / 2);
- // Draw ambient shadow, center aligned within size
- blurPaint.setAlpha(AMBIENT_SHADOW_ALPHA);
- canvas.drawRoundRect(left, top, right, bottom, radius, radius, blurPaint);
+ drawShadow(new Canvas(result), outRect, rectColor, shadowRadius, shadowYOffset, radius);
+ return result;
+ }
- // Draw key shadow, bottom aligned within size
- blurPaint.setAlpha(KEY_SHADOW_ALPHA);
- canvas.drawRoundRect(left, top + shadowYOffset, right, bottom + shadowYOffset,
- radius, radius, blurPaint);
+ public static void drawShadow(Canvas c, RectF bounds, int color,
+ float shadowBlur, float keyShadowDistance, float radius) {
+ Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ p.setColor(color);
- // Draw the circle
- Paint drawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
- drawPaint.setColor(rectColor);
- canvas.drawRoundRect(left, top, right, bottom, radius, radius, drawPaint);
+ // Key shadow
+ p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
+ ColorUtils.setAlphaComponent(Color.BLACK, KEY_SHADOW_ALPHA));
+ c.drawRoundRect(bounds, radius, radius, p);
- return result;
+ // Ambient shadow
+ p.setShadowLayer(shadowBlur, 0, 0,
+ ColorUtils.setAlphaComponent(Color.BLACK, AMBIENT_SHADOW_ALPHA));
+ c.drawRoundRect(bounds, radius, radius, p);
}
public static ShadowGenerator getInstance(Context context) {
diff --git a/src/com/android/launcher3/keyboard/CustomActionsPopup.java b/src/com/android/launcher3/keyboard/CustomActionsPopup.java
index bb0b58add..938955ca2 100644
--- a/src/com/android/launcher3/keyboard/CustomActionsPopup.java
+++ b/src/com/android/launcher3/keyboard/CustomActionsPopup.java
@@ -24,10 +24,10 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
-import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
+import com.android.launcher3.popup.PopupContainerWithArrow;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java
index ffb41b76b..4c83e9ac2 100644
--- a/src/com/android/launcher3/logging/FileLog.java
+++ b/src/com/android/launcher3/logging/FileLog.java
@@ -6,9 +6,8 @@ import android.os.Message;
import android.util.Log;
import android.util.Pair;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import java.io.BufferedReader;
import java.io.File;
@@ -40,7 +39,7 @@ public final class FileLog {
private static File sLogsDirectory = null;
public static void setDir(File logsDir) {
- if (ProviderConfig.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE) {
synchronized (DATE_FORMAT) {
// If the target directory changes, stop any active thread.
if (sHandler != null && !logsDir.equals(sLogsDirectory)) {
@@ -77,7 +76,7 @@ public final class FileLog {
}
public static void print(String tag, String msg, Exception e) {
- if (!ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (!FeatureFlags.IS_DOGFOOD_BUILD) {
return;
}
String out = String.format("%s %s %s", DATE_FORMAT.format(new Date()), tag, msg);
@@ -103,7 +102,7 @@ public final class FileLog {
* @param out if not null, all the persisted logs are copied to the writer.
*/
public static void flushAll(PrintWriter out) throws InterruptedException {
- if (!ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (!FeatureFlags.IS_DOGFOOD_BUILD) {
return;
}
CountDownLatch latch = new CountDownLatch(1);
@@ -136,7 +135,7 @@ public final class FileLog {
@Override
public boolean handleMessage(Message msg) {
- if (sLogsDirectory == null || !ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (sLogsDirectory == null || !FeatureFlags.IS_DOGFOOD_BUILD) {
return true;
}
switch (msg.what) {
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 499fdc7d3..329b7d561 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.logging;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.SparseArray;
import android.view.View;
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 258af1689..7585be613 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -29,7 +29,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.config.FeatureFlags;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
@@ -60,7 +60,7 @@ public class UserEventDispatcher {
private static final String TAG = "UserEvent";
private static final boolean IS_VERBOSE =
- ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
+ FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
public static UserEventDispatcher newInstance(Context context, boolean isInLandscapeMode,
boolean isInMultiWindowMode) {
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 969605483..10fb5828c 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -33,6 +33,7 @@ import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.Provider;
@@ -140,7 +141,7 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
* the workspace has been loaded. We identify a shortcut by its intent.
*/
protected boolean shortcutExists(BgDataModel dataModel, Intent intent, UserHandle user) {
- final String intentWithPkg, intentWithoutPkg;
+ final String compPkgName, intentWithPkg, intentWithoutPkg;
if (intent == null) {
// Skip items with null intents
return true;
@@ -148,19 +149,21 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
if (intent.getComponent() != null) {
// If component is not null, an intent with null package will produce
// the same result and should also be a match.
- String packageName = intent.getComponent().getPackageName();
+ compPkgName = intent.getComponent().getPackageName();
if (intent.getPackage() != null) {
intentWithPkg = intent.toUri(0);
intentWithoutPkg = new Intent(intent).setPackage(null).toUri(0);
} else {
- intentWithPkg = new Intent(intent).setPackage(packageName).toUri(0);
+ intentWithPkg = new Intent(intent).setPackage(compPkgName).toUri(0);
intentWithoutPkg = intent.toUri(0);
}
} else {
+ compPkgName = null;
intentWithPkg = intent.toUri(0);
intentWithoutPkg = intent.toUri(0);
}
+ boolean isLauncherAppTarget = Utilities.isLauncherAppTarget(intent);
synchronized (dataModel) {
for (ItemInfo item : dataModel.itemsIdMap) {
if (item instanceof ShortcutInfo) {
@@ -172,6 +175,16 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) {
return true;
}
+
+ // checking for existing promise icon with same package name
+ if (isLauncherAppTarget
+ && info.isPromise()
+ && info.hasStatusFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)
+ && info.getTargetComponent() != null
+ && compPkgName != null
+ && compPkgName.equals(info.getTargetComponent().getPackageName())) {
+ return true;
+ }
}
}
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 0e73ca6d3..be93be4dc 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -27,16 +27,14 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.config.ProviderConfig;
-import com.android.launcher3.logging.LoggerUtils;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.DumpTargetWrapper;
-import com.android.launcher3.shortcuts.DeepShortcutManager;
-import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.model.nano.LauncherDumpProto;
import com.android.launcher3.model.nano.LauncherDumpProto.ContainerType;
import com.android.launcher3.model.nano.LauncherDumpProto.DumpTarget;
-import com.android.launcher3.model.nano.LauncherDumpProto.ItemType;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
+import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LongArrayMap;
import com.android.launcher3.util.MultiHashMap;
@@ -242,7 +240,7 @@ public class BgDataModel {
switch (item.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
folders.remove(item.id);
- if (ProviderConfig.IS_DOGFOOD_BUILD) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
for (ItemInfo info : itemsIdMap) {
if (info.container == item.id) {
// We are deleting a folder which still contains items that
diff --git a/src/com/android/launcher3/model/CacheDataUpdatedTask.java b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
index 46130fc0b..d7cece488 100644
--- a/src/com/android/launcher3/model/CacheDataUpdatedTask.java
+++ b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
@@ -26,7 +26,6 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.ShortcutInfo;
import java.util.ArrayList;
diff --git a/src/com/android/launcher3/model/DbDowngradeHelper.java b/src/com/android/launcher3/model/DbDowngradeHelper.java
new file mode 100644
index 000000000..cd86b728b
--- /dev/null
+++ b/src/com/android/launcher3/model/DbDowngradeHelper.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.model;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
+import com.android.launcher3.util.IOUtils;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Utility class to handle DB downgrade
+ */
+public class DbDowngradeHelper {
+
+ private static final String TAG = "DbDowngradeHelper";
+
+ private static final String KEY_VERSION = "version";
+ private static final String KEY_DOWNGRADE_TO = "downgrade_to_";
+
+ private final SparseArray<String[]> mStatements = new SparseArray<>();
+ public final int version;
+
+ private DbDowngradeHelper(int version) {
+ this.version = version;
+ }
+
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ ArrayList<String> allCommands = new ArrayList<>();
+
+ for (int i = oldVersion - 1; i >= newVersion; i--) {
+ String[] commands = mStatements.get(i);
+ if (commands == null) {
+ throw new SQLiteException("Downgrade path not supported to version " + i);
+ }
+ Collections.addAll(allCommands, commands);
+ }
+
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+ for (String sql : allCommands) {
+ db.execSQL(sql);
+ }
+ t.commit();
+ }
+ }
+
+ public static DbDowngradeHelper parse(File file) throws JSONException, IOException {
+ JSONObject obj = new JSONObject(new String(IOUtils.toByteArray(file)));
+ DbDowngradeHelper helper = new DbDowngradeHelper(obj.getInt(KEY_VERSION));
+ for (int version = helper.version - 1; version > 0; version--) {
+ if (obj.has(KEY_DOWNGRADE_TO + version)) {
+ JSONArray statements = obj.getJSONArray(KEY_DOWNGRADE_TO + version);
+ String[] parsed = new String[statements.length()];
+ for (int i = 0; i < parsed.length; i++) {
+ parsed[i] = statements.getString(i);
+ }
+ helper.mStatements.put(version, parsed);
+ }
+ }
+ return helper;
+ }
+
+ public static void updateSchemaFile(File schemaFile, int expectedVersion,
+ Context context, int schemaResId) {
+ try {
+ if (DbDowngradeHelper.parse(schemaFile).version >= expectedVersion) {
+ return;
+ }
+ } catch (Exception e) {
+ // Schema error
+ }
+
+ // Write the updated schema
+ try (FileOutputStream fos = new FileOutputStream(schemaFile);
+ InputStream in = context.getResources().openRawResource(schemaResId)) {
+ IOUtils.copy(in, fos);
+ } catch (IOException e) {
+ Log.e(TAG, "Error writing schema file", e);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 36f60b94b..1a2c04d6e 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -219,7 +219,7 @@ public class LoaderCursor extends CursorWrapper {
if (!TextUtils.isEmpty(title)) {
info.title = Utilities.trim(title);
}
- } else if (hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+ } else if (hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
if (TextUtils.isEmpty(info.title)) {
info.title = getTitle();
}
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 4931dca14..032ed780d 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -34,7 +34,7 @@ import com.android.launcher3.LauncherSettings.Settings;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
import java.util.ArrayList;
import java.util.Arrays;
@@ -55,7 +55,7 @@ public class ModelWriter {
public ModelWriter(Context context, BgDataModel dataModel, boolean hasVerticalHotseat) {
mContext = context;
mBgDataModel = dataModel;
- mWorkerExecutor = new LooperExecuter(LauncherModel.getWorkerLooper());
+ mWorkerExecutor = new LooperExecutor(LauncherModel.getWorkerLooper());
mHasVerticalHotseat = hasVerticalHotseat;
}
diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
index 5d04325e8..76b90a8e2 100644
--- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
+++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
@@ -18,15 +18,18 @@ package com.android.launcher3.model;
import android.content.ComponentName;
import com.android.launcher3.AllAppsList;
+import com.android.launcher3.AppInfo;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherModel.Callbacks;
+import com.android.launcher3.PromiseAppInfo;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
+import java.util.ArrayList;
import java.util.HashSet;
/**
@@ -47,6 +50,44 @@ public class PackageInstallStateChangedTask extends ExtendedModelTask {
return;
}
+ synchronized (apps) {
+ PromiseAppInfo updated = null;
+ final ArrayList<AppInfo> removed = new ArrayList<>();
+ for (int i=0; i < apps.size(); i++) {
+ final AppInfo appInfo = apps.get(i);
+ final ComponentName tgtComp = appInfo.getTargetComponent();
+ if (tgtComp != null && tgtComp.getPackageName().equals(mInstallInfo.packageName)) {
+ if (appInfo instanceof PromiseAppInfo) {
+ final PromiseAppInfo promiseAppInfo = (PromiseAppInfo) appInfo;
+ if (mInstallInfo.state == PackageInstallerCompat.STATUS_INSTALLING) {
+ promiseAppInfo.level = mInstallInfo.progress;
+ updated = promiseAppInfo;
+ } else if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
+ apps.removePromiseApp(appInfo);
+ removed.add(appInfo);
+ }
+ }
+ }
+ }
+ if (updated != null) {
+ final PromiseAppInfo updatedPromiseApp = updated;
+ scheduleCallbackTask(new CallbackTask() {
+ @Override
+ public void execute(Callbacks callbacks) {
+ callbacks.bindPromiseAppProgressUpdated(updatedPromiseApp);
+ }
+ });
+ }
+ if (!removed.isEmpty()) {
+ scheduleCallbackTask(new CallbackTask() {
+ @Override
+ public void execute(Callbacks callbacks) {
+ callbacks.bindAppInfosRemoved(removed);
+ }
+ });
+ }
+ }
+
synchronized (dataModel) {
final HashSet<ItemInfo> updates = new HashSet<>();
for (ItemInfo info : dataModel.itemsIdMap) {
@@ -56,7 +97,6 @@ public class PackageInstallStateChangedTask extends ExtendedModelTask {
if (si.isPromise() && (cn != null)
&& mInstallInfo.packageName.equals(cn.getPackageName())) {
si.setInstallProgress(mInstallInfo.progress);
-
if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
// Mark this info as broken.
si.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index f03c9c77c..b58efb647 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -18,9 +18,8 @@ package com.android.launcher3.model;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
+import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
@@ -40,10 +39,12 @@ import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.ManagedProfileHeuristic;
+import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import java.util.ArrayList;
@@ -95,6 +96,9 @@ public class PackageUpdatedTask extends ExtendedModelTask {
for (int i = 0; i < N; i++) {
if (DEBUG) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]);
iconCache.updateIconsForPkg(packages[i], mUser);
+ if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
+ appsList.removePackage(packages[i], Process.myUserHandle());
+ }
appsList.addPackage(context, packages[i], mUser);
}
@@ -222,18 +226,17 @@ public class PackageUpdatedTask extends ExtendedModelTask {
if (cn != null && matcher.matches(si, cn)) {
AppInfo appInfo = addedOrUpdatedApps.get(cn);
- if (si.isPromise() && mOp == OP_ADD) {
- if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+ // For system apps, package manager send OP_UPDATE when an
+ // app is enabled.
+ if (si.isPromise() && (mOp == OP_ADD || mOp == OP_UPDATE)) {
+ if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
// Auto install icon
- PackageManager pm = context.getPackageManager();
- ResolveInfo matched = pm.resolveActivity(
- new Intent(Intent.ACTION_MAIN)
- .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
- PackageManager.MATCH_DEFAULT_ONLY);
- if (matched == null) {
+ LauncherAppsCompat launcherApps
+ = LauncherAppsCompat.getInstance(context);
+ if (!launcherApps.isActivityEnabledForProfile(cn, mUser)) {
// Try to find the best match activity.
- Intent intent = pm.getLaunchIntentForPackage(
- cn.getPackageName());
+ Intent intent = new PackageManagerHelper(context)
+ .getAppLaunchIntent(cn.getPackageName(), mUser);
if (intent != null) {
cn = intent.getComponent();
appInfo = addedOrUpdatedApps.get(cn);
diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
index 278669bdb..bae5c73c1 100644
--- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java
+++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
@@ -19,7 +19,6 @@ package com.android.launcher3.model;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.os.UserHandle;
import com.android.launcher3.LauncherModel;
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index d8a429cba..47e83e5b9 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -21,7 +21,6 @@ import android.os.UserHandle;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.graphics.LauncherIcons;
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 363f1eeb1..fefed7552 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -21,7 +21,6 @@ import android.os.UserHandle;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.compat.UserManagerCompat;
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index e5215c70f..827675a83 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -18,7 +18,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.ShortcutConfigActivityInfo;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
@@ -83,7 +83,7 @@ public class WidgetsModel {
}
setWidgetsAndShortcuts(widgetsAndShortcuts, context, packageUser);
} catch (Exception e) {
- if (!ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
+ if (!FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
// the returned value may be incomplete and will not be refreshed until the next
// time Launcher starts.
// TODO: after figuring out a repro step, introduce a dirty bit to check when
diff --git a/src/com/android/launcher3/pageindicators/CaretDrawable.java b/src/com/android/launcher3/pageindicators/CaretDrawable.java
index 0a00e24e9..349b41cb2 100644
--- a/src/com/android/launcher3/pageindicators/CaretDrawable.java
+++ b/src/com/android/launcher3/pageindicators/CaretDrawable.java
@@ -22,12 +22,11 @@ import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
-import android.graphics.drawable.Drawable;
-
public class CaretDrawable extends Drawable {
public static final float PROGRESS_CARET_POINTING_UP = -1f;
public static final float PROGRESS_CARET_POINTING_DOWN = 1f;
@@ -46,7 +45,7 @@ public class CaretDrawable extends Drawable {
final int strokeWidth = res.getDimensionPixelSize(R.dimen.all_apps_caret_stroke_width);
final int shadowSpread = res.getDimensionPixelSize(R.dimen.all_apps_caret_shadow_spread);
- mCaretPaint.setColor(res.getColor(R.color.workspace_icon_text_color));
+ mCaretPaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary));
mCaretPaint.setAntiAlias(true);
mCaretPaint.setStrokeWidth(strokeWidth);
mCaretPaint.setStyle(Paint.Style.STROKE);
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
index aedf28384..ae10aedee 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
@@ -16,9 +16,7 @@
package com.android.launcher3.pageindicators;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
index 3ceba8419..91fc1f04a 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
@@ -221,7 +221,7 @@ public class PageIndicatorLineCaret extends PageIndicator {
*/
public void updateColor(ExtractedColors extractedColors) {
int originalLineAlpha = mLinePaint.getAlpha();
- int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
+ int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX);
if (color != Color.TRANSPARENT) {
color = ColorUtils.setAlphaComponent(color, 255);
if (color == Color.BLACK) {
diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java
index 384f554e1..b073defa4 100644
--- a/src/com/android/launcher3/popup/PopupItemView.java
+++ b/src/com/android/launcher3/popup/PopupItemView.java
@@ -35,7 +35,7 @@ import android.widget.FrameLayout;
import com.android.launcher3.LogAccelerateInterpolator;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.PillRevealOutlineProvider;
+import com.android.launcher3.anim.PillRevealOutlineProvider;
/**
* An abstract {@link FrameLayout} that supports animating an item's content
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index c62d8771a..fd0010599 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -305,14 +305,12 @@ public class PopupPopulator {
if (view instanceof DeepShortcutView) {
// Expanded system shortcut, with both icon and text shown on white background.
final DeepShortcutView shortcutView = (DeepShortcutView) view;
- shortcutView.getIconView().setBackground(info.getIcon(context,
- android.R.attr.textColorTertiary));
+ shortcutView.getIconView().setBackground(info.getIcon(context));
shortcutView.getBubbleText().setText(info.getLabel(context));
} else if (view instanceof ImageView) {
// Only the system shortcut icon shows on a gray background header.
final ImageView shortcutIcon = (ImageView) view;
- shortcutIcon.setImageDrawable(info.getIcon(context,
- android.R.attr.textColorHint));
+ shortcutIcon.setImageDrawable(info.getIcon(context));
shortcutIcon.setContentDescription(info.getLabel(context));
}
view.setTag(info);
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index f158f7185..a52d1d49b 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -33,10 +33,8 @@ public abstract class SystemShortcut {
mLabelResId = labelResId;
}
- public Drawable getIcon(Context context, int colorAttr) {
- Drawable icon = context.getResources().getDrawable(mIconResId, context.getTheme()).mutate();
- icon.setTint(Themes.getAttrColor(context, colorAttr));
- return icon;
+ public Drawable getIcon(Context context) {
+ return context.getResources().getDrawable(mIconResId, context.getTheme());
}
public String getLabel(Context context) {
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index b0482f8b2..3e4cd0192 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -37,6 +37,7 @@ import com.android.launcher3.DefaultLayoutParser;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherSettings.Settings;
@@ -46,7 +47,6 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.util.LongArrayMap;
@@ -112,7 +112,7 @@ public class ImportDataTask {
screenOps.add(ContentProviderOperation.newInsert(
LauncherSettings.WorkspaceScreens.CONTENT_URI).withValues(v).build());
}
- mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY, screenOps);
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, screenOps);
importWorkspaceItems(allScreens.get(0), screenIdMap);
GridSizeMigrationTask.markForMigration(mContext, mMaxGridSizeX, mMaxGridSizeY, mHotseatSize);
@@ -289,7 +289,7 @@ public class ImportDataTask {
}
if (insertOperations.size() >= BATCH_INSERT_SIZE) {
- mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
insertOperations);
insertOperations.clear();
}
@@ -300,7 +300,7 @@ public class ImportDataTask {
throw new Exception("Insufficient data");
}
if (!insertOperations.isEmpty()) {
- mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
insertOperations);
insertOperations.clear();
}
@@ -319,7 +319,7 @@ public class ImportDataTask {
mHotseatSize = (int) hotseatItems.keyAt(hotseatItems.size() - 1) + 1;
if (!insertOperations.isEmpty()) {
- mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
insertOperations);
}
}
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index 175835011..74373d307 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -19,15 +19,16 @@ package com.android.launcher3.provider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherSettings.WorkspaceScreens;
-import com.android.launcher3.logging.FileLog;
import java.util.ArrayList;
+import java.util.Collection;
/**
* A set of utility methods for Launcher DB used for DB updates and migration.
@@ -44,14 +45,14 @@ public class LauncherDbUtils {
* items are simply deleted.
*/
public static boolean prepareScreenZeroToHostQsb(Context context, SQLiteDatabase db) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Get the existing screens
ArrayList<Long> screenIds = getScreenIdsFromCursor(db.query(WorkspaceScreens.TABLE_NAME,
null, null, null, null, null, WorkspaceScreens.SCREEN_RANK));
if (screenIds.isEmpty()) {
// No update needed
+ t.commit();
return true;
}
if (screenIds.get(0) != 0) {
@@ -68,23 +69,20 @@ public class LauncherDbUtils {
}
// Check if the first row is empty
- try (Cursor c = db.query(Favorites.TABLE_NAME, null,
- "container = -100 and screen = 0 and cellY = 0", null, null, null, null)) {
- if (c.getCount() == 0) {
- // First row is empty, no need to migrate.
- return true;
- }
+ if (DatabaseUtils.queryNumEntries(db, Favorites.TABLE_NAME,
+ "container = -100 and screen = 0 and cellY = 0") == 0) {
+ // First row is empty, no need to migrate.
+ t.commit();
+ return true;
}
new LossyScreenMigrationTask(context, LauncherAppState.getIDP(context), db)
.migrateScreen0();
- db.setTransactionSuccessful();
+ t.commit();
return true;
} catch (Exception e) {
Log.e(TAG, "Failed to update workspace size", e);
return false;
- } finally {
- db.endTransaction();
}
}
@@ -104,19 +102,40 @@ public class LauncherDbUtils {
* Parses the cursor containing workspace screens table and returns the list of screen IDs
*/
public static ArrayList<Long> getScreenIdsFromCursor(Cursor sc) {
- ArrayList<Long> screenIds = new ArrayList<Long>();
try {
- final int idIndex = sc.getColumnIndexOrThrow(WorkspaceScreens._ID);
- while (sc.moveToNext()) {
- try {
- screenIds.add(sc.getLong(idIndex));
- } catch (Exception e) {
- FileLog.d(TAG, "Invalid screen id", e);
- }
- }
+ return iterateCursor(sc,
+ sc.getColumnIndexOrThrow(WorkspaceScreens._ID),
+ new ArrayList<Long>());
} finally {
sc.close();
}
- return screenIds;
+ }
+
+ public static <T extends Collection<Long>> T iterateCursor(Cursor c, int columnIndex, T out) {
+ while (c.moveToNext()) {
+ out.add(c.getLong(columnIndex));
+ }
+ return out;
+ }
+
+ /**
+ * Utility class to simplify managing sqlite transactions
+ */
+ public static class SQLiteTransaction implements AutoCloseable {
+ private final SQLiteDatabase mDb;
+
+ public SQLiteTransaction(SQLiteDatabase db) {
+ mDb = db;
+ db.beginTransaction();
+ }
+
+ public void commit() {
+ mDb.setTransactionSuccessful();
+ }
+
+ @Override
+ public void close() {
+ mDb.endTransaction();
+ }
}
}
diff --git a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
index 4addbfa23..51890d194 100644
--- a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
+++ b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Point;
-import android.util.Log;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -31,7 +30,6 @@ import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.util.LongArrayMap;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* An extension of {@link GridSizeMigrationTask} which migrates only one screen and
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index dc85abad7..00e2644a5 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -27,6 +27,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.util.LogConfig;
import java.io.InvalidObjectException;
@@ -47,16 +48,13 @@ public class RestoreDbTask {
public static boolean performRestore(DatabaseHelper helper) {
SQLiteDatabase db = helper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
new RestoreDbTask().sanitizeDB(helper, db);
- db.setTransactionSuccessful();
+ t.commit();
return true;
} catch (Exception e) {
FileLog.e(TAG, "Failed to verify db", e);
return false;
- } finally {
- db.endTransaction();
}
}
diff --git a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
index ab8de6bd5..e9d2b50ea 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
@@ -23,10 +23,10 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
-import com.android.launcher3.graphics.HolographicOutlineHelper;
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.graphics.HolographicOutlineHelper;
/**
* Extension of {@link DragPreviewProvider} which generates bitmaps scaled to the default icon size.
diff --git a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
index 37047bb36..9c91c87b2 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
@@ -18,15 +18,11 @@ package com.android.launcher3.shortcuts;
import android.annotation.TargetApi;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.os.Build;
import android.os.UserHandle;
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.compat.UserManagerCompat;
-
/**
* Wrapper class for {@link android.content.pm.ShortcutInfo}, representing deep shortcuts into apps.
*
diff --git a/src/com/android/launcher3/testing/LauncherExtension.java b/src/com/android/launcher3/testing/LauncherExtension.java
index aedca8db4..8d4351884 100644
--- a/src/com/android/launcher3/testing/LauncherExtension.java
+++ b/src/com/android/launcher3/testing/LauncherExtension.java
@@ -2,7 +2,6 @@ package com.android.launcher3.testing;
import android.content.Intent;
import android.graphics.Color;
-import android.graphics.Rect;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
@@ -11,8 +10,6 @@ import android.widget.FrameLayout;
import com.android.launcher3.AppInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherCallbacks;
-import com.android.launcher3.allapps.AllAppsSearchBarController;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.util.ComponentKey;
import java.io.FileDescriptor;
@@ -200,11 +197,6 @@ public class LauncherExtension extends Launcher {
}
@Override
- public AllAppsSearchBarController getAllAppsSearchBarController() {
- return null;
- }
-
- @Override
public List<ComponentKey> getPredictedApps() {
// To debug app predictions, enable AlphabeticalAppsList#DEBUG_PREDICTIONS
return new ArrayList<>();
@@ -216,11 +208,6 @@ public class LauncherExtension extends Launcher {
}
@Override
- public void setLauncherSearchCallback(Object callbacks) {
- // Do nothing
- }
-
- @Override
public void onAttachedToWindow() {
}
diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java
index afc45fe35..b80e94d15 100644
--- a/src/com/android/launcher3/util/FocusLogic.java
+++ b/src/com/android/launcher3/util/FocusLogic.java
@@ -23,7 +23,6 @@ import android.view.ViewGroup;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.config.FeatureFlags;
diff --git a/src/com/android/launcher3/util/IOUtils.java b/src/com/android/launcher3/util/IOUtils.java
new file mode 100644
index 000000000..77c21fe92
--- /dev/null
+++ b/src/com/android/launcher3/util/IOUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Supports various IO utility functions
+ */
+public class IOUtils {
+
+ private static final int BUF_SIZE = 0x1000; // 4K
+
+ public static byte[] toByteArray(File file) throws IOException {
+ try (InputStream in = new FileInputStream(file)) {
+ return toByteArray(in);
+ }
+ }
+
+ public static byte[] toByteArray(InputStream in) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ copy(in, out);
+ return out.toByteArray();
+ }
+
+ public static long copy(InputStream from, OutputStream to) throws IOException {
+ byte[] buf = new byte[BUF_SIZE];
+ long total = 0;
+ int r;
+ while ((r = from.read(buf)) != -1) {
+ to.write(buf, 0, r);
+ total += r;
+ }
+ return total;
+ }
+}
diff --git a/src/com/android/launcher3/util/LooperExecuter.java b/src/com/android/launcher3/util/LooperExecutor.java
index 4db999bce..5b7c20bbf 100644
--- a/src/com/android/launcher3/util/LooperExecuter.java
+++ b/src/com/android/launcher3/util/LooperExecutor.java
@@ -25,11 +25,11 @@ import java.util.concurrent.TimeUnit;
/**
* Extension of {@link AbstractExecutorService} which executed on a provided looper.
*/
-public class LooperExecuter extends AbstractExecutorService {
+public class LooperExecutor extends AbstractExecutorService {
private final Handler mHandler;
- public LooperExecuter(Looper looper) {
+ public LooperExecutor(Looper looper) {
mHandler = new Handler(looper);
}
diff --git a/src/com/android/launcher3/util/LooperIdleLock.java b/src/com/android/launcher3/util/LooperIdleLock.java
new file mode 100644
index 000000000..35cac14e3
--- /dev/null
+++ b/src/com/android/launcher3/util/LooperIdleLock.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.util;
+
+import android.os.Looper;
+import android.os.MessageQueue;
+
+import com.android.launcher3.Utilities;
+
+/**
+ * Utility class to block execution until the UI looper is idle.
+ */
+public class LooperIdleLock implements MessageQueue.IdleHandler, Runnable {
+
+ private final Object mLock;
+
+ private boolean mIsLocked;
+
+ public LooperIdleLock(Object lock, Looper looper) {
+ mLock = lock;
+ mIsLocked = true;
+ if (Utilities.ATLEAST_MARSHMALLOW) {
+ looper.getQueue().addIdleHandler(this);
+ } else {
+ // Looper.myQueue() only gives the current queue. Move the execution to the UI thread
+ // so that the IdleHandler is attached to the correct message queue.
+ new LooperExecutor(looper).execute(this);
+ }
+ }
+
+ @Override
+ public void run() {
+ Looper.myQueue().addIdleHandler(this);
+ }
+
+ @Override
+ public boolean queueIdle() {
+ synchronized (mLock) {
+ mIsLocked = false;
+ mLock.notify();
+ }
+ return false;
+ }
+
+ public boolean awaitLocked(long ms) {
+ if (mIsLocked) {
+ try {
+ // Just in case mFlushingWorkerThread changes but we aren't woken up,
+ // wait no longer than 1sec at a time
+ mLock.wait(ms);
+ } catch (InterruptedException ex) {
+ // Ignore
+ }
+ }
+ return mIsLocked;
+ }
+}
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index e12b2d4f1..13034dd9e 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -30,9 +30,11 @@ import android.os.UserHandle;
import android.text.TextUtils;
import com.android.launcher3.AppInfo;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat;
+import java.net.URISyntaxException;
import java.util.List;
/**
@@ -149,4 +151,20 @@ public class PackageManagerHelper {
.appendQueryParameter("id", packageName)
.build());
}
+
+ /**
+ * Creates a new market search intent.
+ */
+ public static Intent getMarketSearchIntent(Context context, String query) {
+ try {
+ Intent intent = Intent.parseUri(context.getString(R.string.market_search_intent), 0);
+ if (!TextUtils.isEmpty(query)) {
+ intent.setData(
+ intent.getData().buildUpon().appendQueryParameter("q", query).build());
+ }
+ return intent;
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/src/com/android/launcher3/util/Preconditions.java b/src/com/android/launcher3/util/Preconditions.java
index 89353e110..7ab0d3103 100644
--- a/src/com/android/launcher3/util/Preconditions.java
+++ b/src/com/android/launcher3/util/Preconditions.java
@@ -19,7 +19,7 @@ package com.android.launcher3.util;
import android.os.Looper;
import com.android.launcher3.LauncherModel;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
/**
* A set of utility methods for thread verification.
@@ -27,25 +27,25 @@ import com.android.launcher3.config.ProviderConfig;
public class Preconditions {
public static void assertNotNull(Object o) {
- if (ProviderConfig.IS_DOGFOOD_BUILD && o == null) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && o == null) {
throw new IllegalStateException();
}
}
public static void assertWorkerThread() {
- if (ProviderConfig.IS_DOGFOOD_BUILD && !isSameLooper(LauncherModel.getWorkerLooper())) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && !isSameLooper(LauncherModel.getWorkerLooper())) {
throw new IllegalStateException();
}
}
public static void assertUIThread() {
- if (ProviderConfig.IS_DOGFOOD_BUILD && !isSameLooper(Looper.getMainLooper())) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && !isSameLooper(Looper.getMainLooper())) {
throw new IllegalStateException();
}
}
public static void assertNonUiThread() {
- if (ProviderConfig.IS_DOGFOOD_BUILD && isSameLooper(Looper.getMainLooper())) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && isSameLooper(Looper.getMainLooper())) {
throw new IllegalStateException();
}
}
diff --git a/src/com/android/launcher3/util/SQLiteCacheHelper.java b/src/com/android/launcher3/util/SQLiteCacheHelper.java
index ef10f97fb..9084bfbd3 100644
--- a/src/com/android/launcher3/util/SQLiteCacheHelper.java
+++ b/src/com/android/launcher3/util/SQLiteCacheHelper.java
@@ -10,7 +10,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
/**
* An extension of {@link SQLiteOpenHelper} with utility methods for a single table cache DB.
@@ -19,7 +19,7 @@ import com.android.launcher3.config.ProviderConfig;
public abstract class SQLiteCacheHelper {
private static final String TAG = "SQLiteCacheHelper";
- private static final boolean NO_ICON_CACHE = ProviderConfig.IS_DOGFOOD_BUILD &&
+ private static final boolean NO_ICON_CACHE = FeatureFlags.IS_DOGFOOD_BUILD &&
Utilities.isPropertyEnabled(LogConfig.MEMORY_ONLY_ICON_CACHE);
private final String mTableName;
diff --git a/src/com/android/launcher3/util/TestingUtils.java b/src/com/android/launcher3/util/TestingUtils.java
index 665c37175..a7cc42b5f 100644
--- a/src/com/android/launcher3/util/TestingUtils.java
+++ b/src/com/android/launcher3/util/TestingUtils.java
@@ -3,7 +3,6 @@ package com.android.launcher3.util;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -11,7 +10,6 @@ import android.widget.FrameLayout;
import com.android.launcher3.CustomAppWidget;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 9bd288244..4cb6ca831 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,12 +16,10 @@
package com.android.launcher3.util;
-import android.util.Log;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewTreeObserver.OnDrawListener;
-import com.android.launcher3.DeferredHandler;
import com.android.launcher3.Launcher;
import java.util.ArrayList;
@@ -34,7 +32,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
OnAttachStateChangeListener {
private final ArrayList<Runnable> mTasks = new ArrayList<>();
- private final DeferredHandler mHandler;
+ private final Executor mExecutor;
private Launcher mLauncher;
private View mAttachedView;
@@ -43,8 +41,8 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
private boolean mLoadAnimationCompleted;
private boolean mFirstDrawCompleted;
- public ViewOnDrawExecutor(DeferredHandler handler) {
- mHandler = handler;
+ public ViewOnDrawExecutor(Executor executor) {
+ mExecutor = executor;
}
public void attachTo(Launcher launcher) {
@@ -92,7 +90,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
// Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
for (final Runnable r : mTasks) {
- mHandler.post(r);
+ mExecutor.execute(r);
}
markCompleted();
}
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index e0a80c679..f47ca3eeb 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -21,9 +21,8 @@ import android.graphics.Color;
import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.view.View;
+
import com.android.launcher3.BaseRecyclerView;
-import com.android.launcher3.model.PackageItemInfo;
-import com.android.launcher3.model.WidgetsModel;
/**
* The widgets recycler view.
diff --git a/src_config/com/android/launcher3/config/ProviderConfig.java b/src_config/com/android/launcher3/BuildConfig.java
index 491fa657a..4df75a1a1 100644
--- a/src_config/com/android/launcher3/config/ProviderConfig.java
+++ b/src_config/com/android/launcher3/BuildConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package com.android.launcher3.config;
+package com.android.launcher3;
-public class ProviderConfig {
-
- public static final String AUTHORITY = "com.android.launcher3.settings".intern();
-
- public static final boolean IS_DOGFOOD_BUILD = true;
+/**
+ * Config file used by Make. This file is automatically generated when using gradle.
+ */
+public class BuildConfig {
+ public static final String APPLICATION_ID = "com.android.launcher3";
}
diff --git a/src_config/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java
index 4e337a2b8..c0184fa91 100644
--- a/src_config/com/android/launcher3/config/FeatureFlags.java
+++ b/src_flags/com/android/launcher3/config/FeatureFlags.java
@@ -20,6 +20,9 @@ package com.android.launcher3.config;
* Defines a set of flags used to control various launcher behaviors
*/
public final class FeatureFlags {
+
+ public static final boolean IS_DOGFOOD_BUILD = true;
+
private FeatureFlags() {}
// Custom flags go below this
@@ -28,12 +31,15 @@ public final class FeatureFlags {
public static boolean LAUNCHER3_USE_SYSTEM_DRAG_DRIVER = true;
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;
+ public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = true;
// 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;
-
+ public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = true;
+ // When enabled the promise icon is visible in all apps while installation an app.
+ public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = true;
+ // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps
+ public static boolean LAUNCHER3_GRADIENT_ALL_APPS = false;
// Feature flag to enable moving the QSB on the 0th screen of the workspace.
public static final boolean QSB_ON_FIRST_SCREEN = true;
@@ -45,10 +51,12 @@ public final class FeatureFlags {
public static final boolean LIGHT_STATUS_BAR = false;
// 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 AdaptiveIconDrawable} will be wrapped in this class.
+ // When enabled, icons not supporting {@link AdaptiveIconDrawable} will be wrapped in {@link FixedScaleDrawable}.
public static final boolean LEGACY_ICON_TREATMENT = true;
// 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;
+ // When enabled, the qsb will be moved to the hotseat.
+ public static final boolean QSB_IN_HOTSEAT = true;
}
diff --git a/tests/res/raw/db_schema_v10.json b/tests/res/raw/db_schema_v10.json
new file mode 100644
index 000000000..a5e290ef7
--- /dev/null
+++ b/tests/res/raw/db_schema_v10.json
@@ -0,0 +1,4 @@
+{
+ "version" : 10,
+ "downgrade_to_9" : []
+} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
index 18570de5b..20b23b070 100644
--- a/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
import android.content.ComponentName;
import android.test.InstrumentationTestCase;
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
index d0ba9074c..883be5aa3 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -10,9 +10,9 @@ import android.net.Uri;
import android.util.Pair;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.LongArrayMap;
import com.android.launcher3.util.Provider;
@@ -178,6 +178,6 @@ public class AddWorkspaceItemsTaskTest extends BaseModelUpdateTaskTestCase {
v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build());
}
- getMockContentResolver().applyBatch(ProviderConfig.AUTHORITY, ops);
+ getMockContentResolver().applyBatch(LauncherProvider.AUTHORITY, ops);
}
}
diff --git a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
index b9944db98..13e09869f 100644
--- a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
+++ b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
@@ -16,7 +16,6 @@ import android.test.ProviderTestCase2;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppFilter;
import com.android.launcher3.AppInfo;
-import com.android.launcher3.DeferredHandler;
import com.android.launcher3.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
@@ -24,7 +23,7 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.BaseModelUpdateTask;
import com.android.launcher3.LauncherModel.Callbacks;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.LauncherProvider;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Provider;
import com.android.launcher3.util.TestLauncherProvider;
@@ -36,6 +35,7 @@ import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.Executor;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.atLeast;
@@ -64,7 +64,7 @@ public class BaseModelUpdateTaskTestCase extends ProviderTestCase2<TestLauncherP
public Callbacks callbacks;
public BaseModelUpdateTaskTestCase() {
- super(TestLauncherProvider.class, ProviderConfig.AUTHORITY);
+ super(TestLauncherProvider.class, LauncherProvider.AUTHORITY);
}
@Override
@@ -102,14 +102,14 @@ public class BaseModelUpdateTaskTestCase extends ProviderTestCase2<TestLauncherP
f.setAccessible(true);
f.set(task, mockModel);
- DeferredHandler mockHandler = mock(DeferredHandler.class);
- f = BaseModelUpdateTask.class.getDeclaredField("mUiHandler");
+ Executor mockExecutor = mock(Executor.class);
+ f = BaseModelUpdateTask.class.getDeclaredField("mUiExecutor");
f.setAccessible(true);
- f.set(task, mockHandler);
+ f.set(task, mockExecutor);
task.execute(appState, bgDataModel, allAppsList);
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
- verify(mockHandler, atLeast(0)).post(captor.capture());
+ verify(mockExecutor, atLeast(0)).execute(captor.capture());
return captor.getAllValues();
}
diff --git a/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java b/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
new file mode 100644
index 000000000..1d9148ba1
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.model;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.LauncherProvider;
+import com.android.launcher3.LauncherProvider.DatabaseHelper;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+/**
+ * Tests for {@link DbDowngradeHelper}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DbDowngradeHelperTest {
+
+ private static final String SCHEMA_FILE = "test_schema.json";
+ private static final String DB_FILE = "test.db";
+
+ private Context mContext;
+ private File mSchemaFile;
+ private File mDbFile;
+
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mSchemaFile = mContext.getFileStreamPath(SCHEMA_FILE);
+ mDbFile = mContext.getDatabasePath(DB_FILE);
+ }
+
+ @Test
+ public void testUpdateSchemaFile() throws Exception {
+ Context myContext = InstrumentationRegistry.getContext();
+ int testResId = myContext.getResources().getIdentifier(
+ "db_schema_v10", "raw", myContext.getPackageName());
+ mSchemaFile.delete();
+ assertFalse(mSchemaFile.exists());
+
+ DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
+ assertTrue(mSchemaFile.exists());
+ assertEquals(10, DbDowngradeHelper.parse(mSchemaFile).version);
+
+ // Schema is updated on version upgrade
+ assertTrue(mSchemaFile.setLastModified(0));
+ DbDowngradeHelper.updateSchemaFile(mSchemaFile, 11, myContext, testResId);
+ assertNotSame(0, mSchemaFile.lastModified());
+
+ // Schema is not updated when version is same
+ assertTrue(mSchemaFile.setLastModified(0));
+ DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
+ assertEquals(0, mSchemaFile.lastModified());
+
+ // Schema is not updated on version downgrade
+ DbDowngradeHelper.updateSchemaFile(mSchemaFile, 3, myContext, testResId);
+ assertEquals(0, mSchemaFile.lastModified());
+ }
+
+ @Test
+ public void testDowngrade_success_v24() throws Exception {
+ setupTestDb();
+
+ TestOpenHelper helper = new TestOpenHelper(24);
+ assertEquals(24, helper.getReadableDatabase().getVersion());
+ helper.close();
+ }
+
+ @Test
+ public void testDowngrade_success_v22() throws Exception {
+ setupTestDb();
+
+ SQLiteOpenHelper helper = new TestOpenHelper(22);
+ assertEquals(22, helper.getWritableDatabase().getVersion());
+
+ // Check column does not exist
+ try (Cursor c = helper.getWritableDatabase().query(Favorites.TABLE_NAME,
+ null, null, null, null, null, null)) {
+ assertEquals(-1, c.getColumnIndex(Favorites.OPTIONS));
+
+ // Check data is present
+ assertEquals(10, c.getCount());
+ }
+ helper.close();
+
+ helper = new DatabaseHelper(mContext, null, DB_FILE) {
+ @Override
+ public void onOpen(SQLiteDatabase db) { }
+ };
+ assertEquals(LauncherProvider.SCHEMA_VERSION, helper.getWritableDatabase().getVersion());
+
+ try (Cursor c = helper.getWritableDatabase().query(Favorites.TABLE_NAME,
+ null, null, null, null, null, null)) {
+ // Check column exists
+ assertNotSame(-1, c.getColumnIndex(Favorites.OPTIONS));
+
+ // Check data is present
+ assertEquals(10, c.getCount());
+ }
+ helper.close();
+ }
+
+ @Test(expected = DowngradeFailException.class)
+ public void testDowngrade_fail_v20() throws Exception {
+ setupTestDb();
+
+ TestOpenHelper helper = new TestOpenHelper(20);
+ helper.getReadableDatabase().getVersion();
+ }
+
+ private void setupTestDb() throws Exception {
+ mSchemaFile.delete();
+ mDbFile.delete();
+
+ DbDowngradeHelper.updateSchemaFile(mSchemaFile, LauncherProvider.SCHEMA_VERSION, mContext,
+ R.raw.downgrade_schema);
+
+ DatabaseHelper dbHelper = new DatabaseHelper(mContext, null, DB_FILE) {
+ @Override
+ public void onOpen(SQLiteDatabase db) { }
+ };
+ // Insert dummy data
+ for (int i = 0; i < 10; i++) {
+ ContentValues values = new ContentValues();
+ values.put(Favorites._ID, i);
+ values.put(Favorites.TITLE, "title " + i);
+ dbHelper.getWritableDatabase().insert(Favorites.TABLE_NAME, null, values);
+ }
+ dbHelper.close();
+ }
+
+ private class TestOpenHelper extends SQLiteOpenHelper {
+
+ public TestOpenHelper(int version) {
+ super(mContext, DB_FILE, null, version);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase) {
+ throw new RuntimeException("DB should already be created");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ throw new RuntimeException("Only downgrade supported");
+ }
+
+ @Override
+ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ try {
+ DbDowngradeHelper.parse(mSchemaFile).onDowngrade(db, oldVersion, newVersion);
+ } catch (Exception e) {
+ throw new DowngradeFailException(e);
+ }
+ }
+ }
+
+ private static class DowngradeFailException extends RuntimeException {
+ public DowngradeFailException(Exception e) {
+ super(e);
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
index fc7fe48fd..fd62d3644 100644
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
+++ b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -1,7 +1,6 @@
package com.android.launcher3.model;
import android.content.ContentValues;
-import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Point;
@@ -10,9 +9,9 @@ import android.test.suitebuilder.annotation.MediumTest;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.model.GridSizeMigrationTask.MultiStepMigrationTask;
import com.android.launcher3.util.TestLauncherProvider;
@@ -40,7 +39,7 @@ public class GridSizeMigrationTaskTest extends ProviderTestCase2<TestLauncherPro
private InvariantDeviceProfile mIdp;
public GridSizeMigrationTaskTest() {
- super(TestLauncherProvider.class, ProviderConfig.AUTHORITY);
+ super(TestLauncherProvider.class, LauncherProvider.AUTHORITY);
}
@Override
diff --git a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java b/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
index d6555620c..ed893c42e 100644
--- a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
+++ b/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
@@ -21,9 +21,8 @@ public class PackageInstallStateChangedTaskTest extends BaseModelUpdateTaskTestC
}
private PackageInstallStateChangedTask newTask(String pkg, int progress) {
- PackageInstallInfo installInfo = new PackageInstallInfo(pkg);
- installInfo.progress = progress;
- installInfo.state = PackageInstallerCompat.STATUS_INSTALLING;
+ int state = PackageInstallerCompat.STATUS_INSTALLING;
+ PackageInstallInfo installInfo = new PackageInstallInfo(pkg, state, progress);
return new PackageInstallStateChangedTask(installInfo);
}
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index df2b66285..97f7b505a 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -39,13 +39,12 @@ import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.ui.LauncherInstrumentationTestCase;
import com.android.launcher3.util.ContentWriter;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.WidgetHostViewLoader;
import java.util.Set;
import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
@@ -340,7 +339,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase {
* Blocks the current thread until all the jobs in the main worker thread are complete.
*/
private void waitUntilLoaderIdle() throws Exception {
- new LooperExecuter(LauncherModel.getWorkerLooper())
+ new LooperExecutor(LauncherModel.getWorkerLooper())
.submit(new Runnable() {
@Override
public void run() { }