diff options
243 files changed, 4984 insertions, 2469 deletions
diff --git a/Android.mk b/Android.mk index c8a53d23d..d41e184f0 100644 --- a/Android.mk +++ b/Android.mk @@ -17,7 +17,7 @@ LOCAL_PATH := $(call my-dir) # -# Build app code. +# Build rule for Launcher3 app. # include $(CLEAR_VARS) @@ -33,7 +33,8 @@ 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) + $(call all-proto-files-under, protos) \ + $(call all-proto-files-under, proto_overrides) LOCAL_RESOURCE_DIR := \ $(LOCAL_PATH)/res \ @@ -42,7 +43,7 @@ LOCAL_RESOURCE_DIR := \ LOCAL_PROGUARD_FLAG_FILES := proguard.flags LOCAL_PROTOC_OPTIMIZE_TYPE := nano -LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ +LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/ LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java LOCAL_AAPT_FLAGS := \ @@ -62,14 +63,65 @@ LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.* include $(BUILD_PACKAGE) # +# Build rule for Launcher3 Go app for Android Go devices. +# +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_STATIC_JAVA_LIBRARIES := \ + android-support-v4 \ + android-support-v7-recyclerview \ + android-support-v7-palette \ + android-support-dynamic-animation + +LOCAL_SRC_FILES := \ + $(call all-java-files-under, src) \ + $(call all-java-files-under, src_config) \ + $(call all-java-files-under, go/src_flags) \ + $(call all-proto-files-under, protos) \ + $(call all-proto-files-under, proto_overrides) + +LOCAL_RESOURCE_DIR := \ + $(LOCAL_PATH)/go/res \ + $(LOCAL_PATH)/res \ + prebuilts/sdk/current/support/v7/recyclerview/res \ + +LOCAL_PROGUARD_FLAG_FILES := proguard.flags + +LOCAL_PROTOC_OPTIMIZE_TYPE := nano +LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/ +LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java + +LOCAL_AAPT_FLAGS := \ + --auto-add-overlay \ + --extra-packages android.support.v7.recyclerview \ + +LOCAL_SDK_VERSION := current +LOCAL_MIN_SDK_VERSION := 21 +LOCAL_PACKAGE_NAME := Launcher3Go +LOCAL_PRIVILEGED_MODULE := true +LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3 + +LOCAL_FULL_LIBS_MANIFEST_FILES := \ + $(LOCAL_PATH)/AndroidManifest.xml \ + $(LOCAL_PATH)/AndroidManifest-common.xml + +LOCAL_MANIFEST_FILE := go/AndroidManifest.xml + +LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.* + +include $(BUILD_PACKAGE) + +# # Launcher proto buffer jar used for development # include $(CLEAR_VARS) -LOCAL_SRC_FILES := $(call all-proto-files-under, protos) +LOCAL_SRC_FILES := $(call all-proto-files-under, protos) $(call all-proto-files-under, proto_overrides) LOCAL_PROTOC_OPTIMIZE_TYPE := nano -LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ +LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/ LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java LOCAL_MODULE_TAGS := optional diff --git a/build.gradle b/build.gradle index c23a29920..886ccace6 100644 --- a/build.gradle +++ b/build.gradle @@ -35,28 +35,49 @@ android { applicationId 'com.android.launcher3' testApplicationId 'com.android.launcher3.tests' } + + l3go { + applicationId 'com.android.launcher3' + testApplicationId 'com.android.launcher3.tests' + } } sourceSets { main { res.srcDirs = ['res'] - java.srcDirs = ['src', 'src_flags'] + java.srcDirs = ['src'] manifest.srcFile 'AndroidManifest-common.xml' - proto.srcDirs 'protos/' + proto { + srcDir 'protos/' + srcDir 'proto_overrides/' + } } androidTest { - java.srcDirs = ['tests/src'] res.srcDirs = ['tests/res'] + java.srcDirs = ['tests/src'] manifest.srcFile "tests/AndroidManifest-common.xml" } aosp { + java.srcDirs = ['src_flags'] manifest.srcFile "AndroidManifest.xml" } aospAndroidTest { manifest.srcFile "tests/AndroidManifest.xml" } + + l3go { + res.srcDirs = ['go/res'] + java.srcDirs = ['go/src_flags'] + // Note: we are using the Launcher3 manifest here because the gradle manifest-merger uses + // different attributes than the build system. + manifest.srcFile "AndroidManifest.xml" + } + + l3goAndroidTest { + manifest.srcFile "tests/AndroidManifest.xml" + } } } @@ -71,10 +92,10 @@ dependencies { compile "com.android.support:support-dynamic-animation:${SUPPORT_LIBS_VERSION}" compile "com.android.support:recyclerview-v7:${SUPPORT_LIBS_VERSION}" compile "com.android.support:palette-v7:${SUPPORT_LIBS_VERSION}" - compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-2' + compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7' testCompile 'junit:junit:4.12' - androidTestCompile "org.mockito:mockito-core:1.+" + androidTestCompile "org.mockito:mockito-core:1.9.5" androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' androidTestCompile 'com.android.support.test:runner:0.5' @@ -92,6 +113,7 @@ protobuf { task.builtins { remove java javanano { + option "java_package=launcher_log_extension.proto|com.android.launcher3.userevent.nano" 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/go/AndroidManifest.xml b/go/AndroidManifest.xml new file mode 100644 index 000000000..ed8e0ad3b --- /dev/null +++ b/go/AndroidManifest.xml @@ -0,0 +1,53 @@ +<?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. +*/ +--> +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.android.launcher3" > + + <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/> + + <application + android:backupAgent="com.android.launcher3.LauncherBackupAgent" + android:fullBackupOnly="true" + android:fullBackupContent="@xml/backupscheme" + android:hardwareAccelerated="true" + android:icon="@drawable/ic_launcher_home" + android:label="@string/derived_app_name" + android:theme="@style/LauncherTheme" + android:largeHeap="@bool/config_largeHeap" + android:restoreAnyVersion="true" + android:supportsRtl="true" > + + <!-- Activity for handling PinItemRequest. Only supports shortcuts --> + <activity android:name="com.android.launcher3.dragndrop.AddItemActivity" + android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert" + android:excludeFromRecents="true" + android:autoRemoveFromRecents="true" + android:label="@string/action_add_to_workspace" + tools:merge="override" > + <intent-filter> + <action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" /> + </intent-filter> + </activity> + + </application> + +</manifest> diff --git a/go/res/drawable/ic_widget.xml b/go/res/drawable/ic_widget.xml new file mode 100644 index 000000000..53368760e --- /dev/null +++ b/go/res/drawable/ic_widget.xml @@ -0,0 +1,25 @@ +<!-- +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="48dp" + android:height="48dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M3.9,18.35c2.5-2.49,5.78-3.64,10.14-3.64v3.05c0,0.47,0.57,0.71,0.9,0.37l5.74-5.74c0.41-0.41,0.41-1.08,0-1.49l-5.74-5.74 + c-0.33-0.33-0.9-0.1-0.9,0.37v2.95c-6.32,0.9-9.56,4.9-11.02,9.34C2.86,18.34,3.51,18.74,3.9,18.35z"/> +</vector> diff --git a/go/res/layout/widget_cell_content.xml b/go/res/layout/widget_cell_content.xml new file mode 100644 index 000000000..49506d9be --- /dev/null +++ b/go/res/layout/widget_cell_content.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="@dimen/widget_preview_label_vertical_padding" + android:paddingBottom="@dimen/widget_preview_label_vertical_padding" + android:paddingLeft="@dimen/widget_preview_label_horizontal_padding" + android:paddingRight="@dimen/widget_preview_label_horizontal_padding" + android:orientation="horizontal"> + + <!-- The name of the widget. --> + <TextView + android:id="@+id/widget_name" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:ellipsize="end" + android:fadingEdge="horizontal" + android:fontFamily="sans-serif-condensed" + android:gravity="center" + android:singleLine="true" + android:maxLines="1" + android:textColor="?android:attr/textColorSecondary" + android:textSize="14sp" /> + + <!-- The original dimensions of the widget (can't be the same text as above due to different + style. --> + <TextView + android:id="@+id/widget_dims" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="5dp" + android:layout_marginLeft="5dp" + android:visibility="gone" + android:textColor="?android:attr/textColorSecondary" + android:textSize="14sp" + android:fontFamily="sans-serif-condensed" + android:alpha="0.8" /> + </LinearLayout> + + <!-- The image of the widget. This view does not support padding. Any placement adjustment + should be done using margins. --> + <com.android.launcher3.widget.WidgetImageView + android:id="@+id/widget_preview" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> +</merge>
\ No newline at end of file diff --git a/go/res/values-af/strings.xml b/go/res/values-af/strings.xml new file mode 100644 index 000000000..10ac473c1 --- /dev/null +++ b/go/res/values-af/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Raak en hou om \'n kortpad op te tel."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Kortpaaie"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-kortpaaie"</string> +</resources> diff --git a/go/res/values-am/strings.xml b/go/res/values-am/strings.xml new file mode 100644 index 000000000..b3b253f42 --- /dev/null +++ b/go/res/values-am/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"አንድ አቋራጭ ለመውሰድ ነክተው ይያዙ"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"አንድ አቋራጭ ለመውሰድ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።"</string> + <string name="widget_button_text" msgid="4221900832360456858">"አቋራጮች"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> አቋራጮች"</string> +</resources> diff --git a/go/res/values-ar/strings.xml b/go/res/values-ar/strings.xml new file mode 100644 index 000000000..2b3b80746 --- /dev/null +++ b/go/res/values-ar/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"المس مع الاستمرار لاختيار اختصار."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"يمكنك النقر نقرًا مزدوجًا مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string> + <string name="widget_button_text" msgid="4221900832360456858">"الاختصارات"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"اختصارات <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-az-rAZ/strings.xml b/go/res/values-az-rAZ/strings.xml new file mode 100644 index 000000000..c4b8cb780 --- /dev/null +++ b/go/res/values-az-rAZ/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Qısayolu seçmək üçün toxunub saxlayın."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Qısayollar"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> qısayolları"</string> +</resources> diff --git a/go/res/values-az/strings.xml b/go/res/values-az/strings.xml new file mode 100644 index 000000000..c4b8cb780 --- /dev/null +++ b/go/res/values-az/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Qısayolu seçmək üçün toxunub saxlayın."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Qısayollar"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> qısayolları"</string> +</resources> diff --git a/go/res/values-b+sr+Latn/strings.xml b/go/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000..0da569941 --- /dev/null +++ b/go/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i zadržite da biste izabrali prečicu."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice za <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-be/strings.xml b/go/res/values-be/strings.xml new file mode 100644 index 000000000..4189e35fa --- /dev/null +++ b/go/res/values-be/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Ярлыкі"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Ярлыкі <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-bg/strings.xml b/go/res/values-bg/strings.xml new file mode 100644 index 000000000..1b85992d9 --- /dev/null +++ b/go/res/values-bg/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Докоснете и задръжте за избор на пряк път."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Докоснете двукратно и задръжте за избор на пряк път или използвайте персонализирани действия."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Преки пътища"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Преки пътища за <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-bn/strings.xml b/go/res/values-bn/strings.xml new file mode 100644 index 000000000..c56c925a2 --- /dev/null +++ b/go/res/values-bn/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"কোনও শর্টকাট বেছে নিতে টাচ করে ধরে রাখুন।"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"কোনও শর্টকাট বেছে নিতে ডাবল ট্যাপ করে ধরে রাখুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন।"</string> + <string name="widget_button_text" msgid="4221900832360456858">"শর্টকাট"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> এর শর্টকাট"</string> +</resources> diff --git a/go/res/values-bs-rBA/strings.xml b/go/res/values-bs-rBA/strings.xml new file mode 100644 index 000000000..7042468b4 --- /dev/null +++ b/go/res/values-bs-rBA/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i držite da uzmete prečicu."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i držite da uzmete prečicu ili koristite prilagođene akcije."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-bs/strings.xml b/go/res/values-bs/strings.xml new file mode 100644 index 000000000..7042468b4 --- /dev/null +++ b/go/res/values-bs/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i držite da uzmete prečicu."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i držite da uzmete prečicu ili koristite prilagođene akcije."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ca/strings.xml b/go/res/values-ca/strings.xml new file mode 100644 index 000000000..3b5c3f7b5 --- /dev/null +++ b/go/res/values-ca/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén premuda una drecera per seleccionar-la."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Dreceres"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Dreceres de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-cs/strings.xml b/go/res/values-cs/strings.xml new file mode 100644 index 000000000..e4018f2c0 --- /dev/null +++ b/go/res/values-cs/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Zkratku vyberete podržením."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Zkratky"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Zkratky aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-da/strings.xml b/go/res/values-da/strings.xml new file mode 100644 index 000000000..821d36a7d --- /dev/null +++ b/go/res/values-da/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Hold en genvej nede for at samle den op."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tryk to gange, og hold en genvej nede for at samle den op og bruge tilpassede handlinger."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Genveje"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-genveje"</string> +</resources> diff --git a/go/res/values-de/strings.xml b/go/res/values-de/strings.xml new file mode 100644 index 000000000..43a1b3a9e --- /dev/null +++ b/go/res/values-de/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Doppeltippen und halten, um eine Verknüpfung auszuwählen."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Verknüpfungen"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-Verknüpfungen"</string> +</resources> diff --git a/go/res/values-el/strings.xml b/go/res/values-el/strings.xml new file mode 100644 index 000000000..ae59907d1 --- /dev/null +++ b/go/res/values-el/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Αγγίξτε παρατεταμένα για να σηκώσετε μια συντόμευση."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Πατήσετε δύο φορές παρατεταμένα για να σηκώσετε μια συντόμευση ή για να χρησιμοποιήσετε προσαρμοσμένες ενέργειες."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Συντομεύσεις"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Συντομεύσεις <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-en-rAU/strings.xml b/go/res/values-en-rAU/strings.xml new file mode 100644 index 000000000..2ee2c2645 --- /dev/null +++ b/go/res/values-en-rAU/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Touch & hold to pick up a shortcut."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap & hold to pick up a shortcut or use custom actions."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string> +</resources> diff --git a/go/res/values-en-rGB/strings.xml b/go/res/values-en-rGB/strings.xml new file mode 100644 index 000000000..2ee2c2645 --- /dev/null +++ b/go/res/values-en-rGB/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Touch & hold to pick up a shortcut."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap & hold to pick up a shortcut or use custom actions."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string> +</resources> diff --git a/go/res/values-en-rIN/strings.xml b/go/res/values-en-rIN/strings.xml new file mode 100644 index 000000000..2ee2c2645 --- /dev/null +++ b/go/res/values-en-rIN/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Touch & hold to pick up a shortcut."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap & hold to pick up a shortcut or use custom actions."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string> +</resources> diff --git a/go/res/values-es-rUS/strings.xml b/go/res/values-es-rUS/strings.xml new file mode 100644 index 000000000..5212c035d --- /dev/null +++ b/go/res/values-es-rUS/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén presionado para elegir un acceso directo."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Accesos directos"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Accesos directos de <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-es/strings.xml b/go/res/values-es/strings.xml new file mode 100644 index 000000000..3ae45889c --- /dev/null +++ b/go/res/values-es/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén pulsado el acceso directo que quieras."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toca dos veces y mantén pulsado el acceso directo o utiliza acciones personalizadas."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Accesos directos"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Accesos directos de <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-et/strings.xml b/go/res/values-et/strings.xml new file mode 100644 index 000000000..2513e65a3 --- /dev/null +++ b/go/res/values-et/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Otsetee valimiseks puudutage seda pikalt."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Otseteed"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> otseteed"</string> +</resources> diff --git a/go/res/values-eu/strings.xml b/go/res/values-eu/strings.xml new file mode 100644 index 000000000..9949ef091 --- /dev/null +++ b/go/res/values-eu/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Eduki sakatuta lasterbide bat aukeratzeko."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Lasterbideak"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioaren lasterbidea"</string> +</resources> diff --git a/go/res/values-fa/strings.xml b/go/res/values-fa/strings.xml new file mode 100644 index 000000000..8bc5256d1 --- /dev/null +++ b/go/res/values-fa/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"برای انتخاب یک میانبر، لمس کنید و نگهدارید."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"برای انتخاب یک میانبر، دو ضربه سریع بزنید و نگهدارید یا از اقدامهای سفارشی استفاده کنید."</string> + <string name="widget_button_text" msgid="4221900832360456858">"میانبرها"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"میانبرهای <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-fi/strings.xml b/go/res/values-fi/strings.xml new file mode 100644 index 000000000..da9b0e1c4 --- /dev/null +++ b/go/res/values-fi/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Valitse pikakuvake painamalla sitä pitkään."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Pikakuvakkeet"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Kohteen <xliff:g id="NAME">%1$s</xliff:g> pikakuvakkeet"</string> +</resources> diff --git a/go/res/values-fr-rCA/strings.xml b/go/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000..c7fd6d642 --- /dev/null +++ b/go/res/values-fr-rCA/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Maintenez un doigt sur le raccourci pour l\'ajouter"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Raccourcis"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Raccourcis : <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-fr/strings.xml b/go/res/values-fr/strings.xml new file mode 100644 index 000000000..238fe73d7 --- /dev/null +++ b/go/res/values-fr/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Appui prolongé pour sélectionner raccourci."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Appuyez 2 fois et maintenez pression pour sélectionner raccourci ou utilisez actions personnalisées."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Raccourcis"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Raccourcis <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-gl/strings.xml b/go/res/values-gl/strings.xml new file mode 100644 index 000000000..31621d5c2 --- /dev/null +++ b/go/res/values-gl/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén premido un atallo para seleccionalo."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Atallos"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atallos da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-gu/strings.xml b/go/res/values-gu/strings.xml new file mode 100644 index 000000000..bdb549ff7 --- /dev/null +++ b/go/res/values-gu/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"એક શૉર્ટકટ ચૂંટવા ટૅપ કરી રાખો."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરી રાખો."</string> + <string name="widget_button_text" msgid="4221900832360456858">"શૉર્ટકટ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> શૉર્ટકટ"</string> +</resources> diff --git a/go/res/values-hi/strings.xml b/go/res/values-hi/strings.xml new file mode 100644 index 000000000..bc057760f --- /dev/null +++ b/go/res/values-hi/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"शॉर्टकट चुनने के लिए छूकर रखें."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"शॉर्टकट चुनने के लिए डबल टैप करके रखें या कस्टम कार्रवाइयों का उपयोग करें."</string> + <string name="widget_button_text" msgid="4221900832360456858">"शॉर्टकट"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> शॉर्टकट"</string> +</resources> diff --git a/go/res/values-hr/strings.xml b/go/res/values-hr/strings.xml new file mode 100644 index 000000000..fccdeb59d --- /dev/null +++ b/go/res/values-hr/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i zadržite kako biste podigli prečac."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Prečaci"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečaci za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-hu/strings.xml b/go/res/values-hu/strings.xml new file mode 100644 index 000000000..369c22745 --- /dev/null +++ b/go/res/values-hu/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Felvételhez tartsa nyomva a parancsikont."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Parancsikonok"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-parancsikonok"</string> +</resources> diff --git a/go/res/values-hy/strings.xml b/go/res/values-hy/strings.xml new file mode 100644 index 000000000..4747f6df3 --- /dev/null +++ b/go/res/values-hy/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:"</string> + <string name="widget_button_text" msgid="4221900832360456858">"Դյուրանցումներ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> դյուրանցումներ"</string> +</resources> diff --git a/go/res/values-in/strings.xml b/go/res/values-in/strings.xml new file mode 100644 index 000000000..c8b9da306 --- /dev/null +++ b/go/res/values-in/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tap lama untuk memilih pintasan."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Pintasan"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Pintasan <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-is/strings.xml b/go/res/values-is/strings.xml new file mode 100644 index 000000000..b8bb92374 --- /dev/null +++ b/go/res/values-is/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Haltu fingri á flýtileið til að grípa hana."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Flýtileiðir"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> flýtileiðir"</string> +</resources> diff --git a/go/res/values-it/strings.xml b/go/res/values-it/strings.xml new file mode 100644 index 000000000..bc5d99863 --- /dev/null +++ b/go/res/values-it/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tocca e tieni premuto per scegliere la scorciatoia"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Scorciatoie"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Scorciatoie di <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-iw/strings.xml b/go/res/values-iw/strings.xml new file mode 100644 index 000000000..f541d4d31 --- /dev/null +++ b/go/res/values-iw/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"כדי להוסיף קיצור דרך, מקישים עליו פעמיים ומחזיקים."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"כדי להוסיף קיצור דרך או להשתמש בפעולות מותאמות אישית, מקישים על קיצור הדרך פעמיים ומחזיקים."</string> + <string name="widget_button_text" msgid="4221900832360456858">"קיצורי דרך"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"קיצורי דרך לאפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ja/strings.xml b/go/res/values-ja/strings.xml new file mode 100644 index 000000000..8f02d7f4e --- /dev/null +++ b/go/res/values-ja/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ショートカットを追加するには押し続けます。"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ダブルタップ後に押し続けてショートカットを選択するか、カスタム操作を使用してください。"</string> + <string name="widget_button_text" msgid="4221900832360456858">"ショートカット"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"「<xliff:g id="NAME">%1$s</xliff:g>」のショートカット"</string> +</resources> diff --git a/go/res/values-ka-rGE/strings.xml b/go/res/values-ka-rGE/strings.xml new file mode 100644 index 000000000..1b4653478 --- /dev/null +++ b/go/res/values-ka-rGE/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string> + <string name="widget_button_text" msgid="4221900832360456858">"მალსახმობები"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-ის მალსახმობები"</string> +</resources> diff --git a/go/res/values-ka/strings.xml b/go/res/values-ka/strings.xml new file mode 100644 index 000000000..1b4653478 --- /dev/null +++ b/go/res/values-ka/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string> + <string name="widget_button_text" msgid="4221900832360456858">"მალსახმობები"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-ის მალსახმობები"</string> +</resources> diff --git a/go/res/values-kk/strings.xml b/go/res/values-kk/strings.xml new file mode 100644 index 000000000..e909818af --- /dev/null +++ b/go/res/values-kk/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Таңбашаны таңдау үшін оны түртіп, ұстап тұрыңыз."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Таңбашаны таңдау немесе арнаулы әрекеттерді пайдалану үшін екі рет түртіп, ұстап тұрыңыз."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Таңбашалар"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> таңбаша"</string> +</resources> diff --git a/go/res/values-km/strings.xml b/go/res/values-km/strings.xml new file mode 100644 index 000000000..40082a4b9 --- /dev/null +++ b/go/res/values-km/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ប៉ះ ហើយចុចឲ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ។"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ប៉ះពីរដង ហើយចុចឱ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"</string> + <string name="widget_button_text" msgid="4221900832360456858">"ផ្លូវកាត់"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ផ្លូវកាត់សម្រាប់ <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-kn/strings.xml b/go/res/values-kn/strings.xml new file mode 100644 index 000000000..9c121fd29 --- /dev/null +++ b/go/res/values-kn/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ."</string> + <string name="widget_button_text" msgid="4221900832360456858">"ಶಾರ್ಟ್ಕಟ್ಗಳು"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ಶಾರ್ಟ್ಕಟ್ಗಳು"</string> +</resources> diff --git a/go/res/values-ko/strings.xml b/go/res/values-ko/strings.xml new file mode 100644 index 000000000..60f925e36 --- /dev/null +++ b/go/res/values-ko/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"바로가기를 선택하려면 길게 터치하세요."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"바로가기를 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 액션을 사용합니다."</string> + <string name="widget_button_text" msgid="4221900832360456858">"바로가기"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> 바로가기"</string> +</resources> diff --git a/go/res/values-ky-rKG/strings.xml b/go/res/values-ky-rKG/strings.xml new file mode 100644 index 000000000..4c7e973ce --- /dev/null +++ b/go/res/values-ky-rKG/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Кыска жолду тандоо үчүн басып туруңуз."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Кыска жолдор"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> кыска жол"</string> +</resources> diff --git a/go/res/values-ky/strings.xml b/go/res/values-ky/strings.xml new file mode 100644 index 000000000..4c7e973ce --- /dev/null +++ b/go/res/values-ky/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Кыска жолду тандоо үчүн басып туруңуз."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Кыска жолдор"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> кыска жол"</string> +</resources> diff --git a/go/res/values-lo-rLA/strings.xml b/go/res/values-lo-rLA/strings.xml new file mode 100644 index 000000000..7864884ac --- /dev/null +++ b/go/res/values-lo-rLA/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."</string> + <string name="widget_button_text" msgid="4221900832360456858">"ປຸ່ມລັດ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ປຸ່ມລັດ <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-lo/strings.xml b/go/res/values-lo/strings.xml new file mode 100644 index 000000000..7864884ac --- /dev/null +++ b/go/res/values-lo/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."</string> + <string name="widget_button_text" msgid="4221900832360456858">"ປຸ່ມລັດ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ປຸ່ມລັດ <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-lt/strings.xml b/go/res/values-lt/strings.xml new file mode 100644 index 000000000..8f49032cf --- /dev/null +++ b/go/res/values-lt/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dukart pal. ir palaik., kad pasir. spart. klav."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Spartieji klavišai"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"„<xliff:g id="NAME">%1$s</xliff:g>“ spartieji klavišai"</string> +</resources> diff --git a/go/res/values-lv/strings.xml b/go/res/values-lv/strings.xml new file mode 100644 index 000000000..04315ebaa --- /dev/null +++ b/go/res/values-lv/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Lai izvēlētos saīsni, pieskarieties un turiet to."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to vai arī veiciet pielāgotas darbības."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Saīsnes"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Lietotnes <xliff:g id="NAME">%1$s</xliff:g> saīsnes"</string> +</resources> diff --git a/go/res/values-mk/strings.xml b/go/res/values-mk/strings.xml new file mode 100644 index 000000000..52d66b5e2 --- /dev/null +++ b/go/res/values-mk/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Допрете двапати и задржете за да изберете кратенка."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Допрете двапати и задржете за да изберете кратенка или да користите приспособени дејства."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Кратенки"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Кратенки за <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ml/strings.xml b/go/res/values-ml/strings.xml new file mode 100644 index 000000000..b3c12e16e --- /dev/null +++ b/go/res/values-ml/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ഒരു കുറുക്കുവഴി ചേർക്കുന്നതിന് അത് സ്പർശിച്ച് പിടിക്കുക."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ഒരു കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."</string> + <string name="widget_button_text" msgid="4221900832360456858">"കുറുക്കുവഴികൾ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> കുറുക്കുവഴികൾ"</string> +</resources> diff --git a/go/res/values-mn/strings.xml b/go/res/values-mn/strings.xml new file mode 100644 index 000000000..c89dfd1bd --- /dev/null +++ b/go/res/values-mn/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Товчлол авах бол удаан дарна уу."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Товчлол авах болон тохируулсан үйлдлийг ашиглахын тулд хоёр товшоод хүлээнэ үү."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Товчлол"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-н товчлол"</string> +</resources> diff --git a/go/res/values-mr/strings.xml b/go/res/values-mr/strings.xml new file mode 100644 index 000000000..2c767b4f1 --- /dev/null +++ b/go/res/values-mr/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string> + <string name="widget_button_text" msgid="4221900832360456858">"शॉर्टकट"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> शॉर्टकट"</string> +</resources> diff --git a/go/res/values-ms/strings.xml b/go/res/values-ms/strings.xml new file mode 100644 index 000000000..42add9a19 --- /dev/null +++ b/go/res/values-ms/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Sentuh & tahan untuk mengambil pintasan."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ketik dua kali & tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Pintasan"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Pintasan <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-my/strings.xml b/go/res/values-my/strings.xml new file mode 100644 index 000000000..5784df63b --- /dev/null +++ b/go/res/values-my/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"လက်ကွက်ဖြတ်လမ်းတစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"လက်ကွက်ဖြတ်လမ်းကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန်နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string> + <string name="widget_button_text" msgid="4221900832360456858">"ဖြတ်လမ်းလင့်ခ်များ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ဖြတ်လမ်းလင့်ခ်များ"</string> +</resources> diff --git a/go/res/values-nb/strings.xml b/go/res/values-nb/strings.xml new file mode 100644 index 000000000..2a5ffb6e7 --- /dev/null +++ b/go/res/values-nb/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Trykk og hold for å velge en snarvei."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Snarveier"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-snarveier"</string> +</resources> diff --git a/go/res/values-ne/strings.xml b/go/res/values-ne/strings.xml new file mode 100644 index 000000000..0be0375f3 --- /dev/null +++ b/go/res/values-ne/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"कुनै सटकर्ट छनौट गर्न छोइराख्नुहोस्।"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"कुनै सर्टकट छनौट गर्न दुईपटक ट्याप गरेर होल्ड गर्नुहोस् वा रोजेका कारबाहीहरू प्रयोग गर्नुहोस्।"</string> + <string name="widget_button_text" msgid="4221900832360456858">"सर्टकटहरू"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> सर्टकटहरू"</string> +</resources> diff --git a/go/res/values-nl/strings.xml b/go/res/values-nl/strings.xml new file mode 100644 index 000000000..5bcd016b4 --- /dev/null +++ b/go/res/values-nl/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tik en houd vast om snelkoppeling toe te voegen."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Snelkoppelingen"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-snelkoppelingen"</string> +</resources> diff --git a/go/res/values-pa/strings.xml b/go/res/values-pa/strings.xml new file mode 100644 index 000000000..f3982ab71 --- /dev/null +++ b/go/res/values-pa/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਡਬਲ-ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ ਜਾਂ ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"</string> + <string name="widget_button_text" msgid="4221900832360456858">"ਸ਼ਾਰਟਕੱਟ"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ਸ਼ਾਰਟਕੱਟ"</string> +</resources> diff --git a/go/res/values-pl/strings.xml b/go/res/values-pl/strings.xml new file mode 100644 index 000000000..45a1dc2ca --- /dev/null +++ b/go/res/values-pl/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Kliknij i przytrzymaj, by wybrać skrót."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Skróty"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> – skróty"</string> +</resources> diff --git a/go/res/values-pt-rPT/strings.xml b/go/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000..7a75a0545 --- /dev/null +++ b/go/res/values-pt-rPT/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Toque sem soltar para escolher um atalho."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Atalhos"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atalhos da aplicação <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-pt/strings.xml b/go/res/values-pt/strings.xml new file mode 100644 index 000000000..53bbfc41a --- /dev/null +++ b/go/res/values-pt/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Toque e segure para selecionar um atalho."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Atalhos"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atalhos do app <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ro/strings.xml b/go/res/values-ro/strings.xml new file mode 100644 index 000000000..75d1796b5 --- /dev/null +++ b/go/res/values-ro/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Atingeți și țineți apăsat pentru a selecta o comandă rapidă."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Atingeți de două ori și țineți apăsat pentru comandă rapidă sau folosiți acțiuni personalizate."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Comenzi rapide"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Comenzi rapide pentru <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ru/strings.xml b/go/res/values-ru/strings.xml new file mode 100644 index 000000000..9c5c8cd34 --- /dev/null +++ b/go/res/values-ru/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Чтобы выбрать ярлык, нажмите на него и удерживайте."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Чтобы выбрать ярлык или использовать специальные действия, нажмите на него дважды и не отпускайте."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Ярлыки"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>: ярлыки"</string> +</resources> diff --git a/go/res/values-si-rLK/strings.xml b/go/res/values-si-rLK/strings.xml new file mode 100644 index 000000000..4b25c90b0 --- /dev/null +++ b/go/res/values-si-rLK/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string> + <string name="widget_button_text" msgid="4221900832360456858">"කෙටි මං"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"කෙටි මං <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-si/strings.xml b/go/res/values-si/strings.xml new file mode 100644 index 000000000..4b25c90b0 --- /dev/null +++ b/go/res/values-si/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string> + <string name="widget_button_text" msgid="4221900832360456858">"කෙටි මං"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"කෙටි මං <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-sk/strings.xml b/go/res/values-sk/strings.xml new file mode 100644 index 000000000..fc0293373 --- /dev/null +++ b/go/res/values-sk/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Skratku pridáte pridržaním."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Skratky"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Skratky aplikácie <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-sl/strings.xml b/go/res/values-sl/strings.xml new file mode 100644 index 000000000..6ecedfb16 --- /dev/null +++ b/go/res/values-sl/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Pridržite bližnjico, da jo izberete."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Bližnjice"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Bližnjice za <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-sq/strings.xml b/go/res/values-sq/strings.xml new file mode 100644 index 000000000..bb74db6b5 --- /dev/null +++ b/go/res/values-sq/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Prek dhe mbaj prekur për të zgjedhur një shkurtore."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Shkurtoret"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shkurtore"</string> +</resources> diff --git a/go/res/values-sr/strings.xml b/go/res/values-sr/strings.xml new file mode 100644 index 000000000..0b9aea2f9 --- /dev/null +++ b/go/res/values-sr/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Додирните и задржите да бисте изабрали пречицу."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Двапут додирните и задржите да бисте изабрали пречицу или користите прилагођене радње."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Пречице"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Пречице за <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-sv/strings.xml b/go/res/values-sv/strings.xml new file mode 100644 index 000000000..c3f434c27 --- /dev/null +++ b/go/res/values-sv/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tryck länge om du vill ta upp en genväg."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Genvägar"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Genvägar för <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-sw/strings.xml b/go/res/values-sw/strings.xml new file mode 100644 index 000000000..0379ed012 --- /dev/null +++ b/go/res/values-sw/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Gusa na ushikilie ili uchague njia ya mkato."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Gonga mara mbili na ushikilie ile uchague njia ya mkato au utumie vitendo maalum."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Njia za mkato"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Njia za mkato za <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ta/strings.xml b/go/res/values-ta/strings.xml new file mode 100644 index 000000000..50059b65f --- /dev/null +++ b/go/res/values-ta/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"குறுக்குவழியைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"குறுக்குவழியை சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string> + <string name="widget_button_text" msgid="4221900832360456858">"குறுக்குவழிகள்"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> குறுக்குவழிகள்"</string> +</resources> diff --git a/go/res/values-te/strings.xml b/go/res/values-te/strings.xml new file mode 100644 index 000000000..0bdf74334 --- /dev/null +++ b/go/res/values-te/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"సత్వరమార్గాన్ని ఎంచుకోవడానికి తాకి & నొక్కి ఉంచండి."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"సత్వరమార్గాన్ని ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి &ఉంచండి."</string> + <string name="widget_button_text" msgid="4221900832360456858">"సత్వరమార్గాలు"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> సత్వరమార్గాలు"</string> +</resources> diff --git a/go/res/values-th/strings.xml b/go/res/values-th/strings.xml new file mode 100644 index 000000000..e73d89fb0 --- /dev/null +++ b/go/res/values-th/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"แตะค้างไว้เพื่อเลือกทางลัด"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"แตะสองครั้งค้างไว้เพื่อเลือกทางลัดหรือใช้การกระทำที่กำหนดเอง"</string> + <string name="widget_button_text" msgid="4221900832360456858">"ทางลัด"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ทางลัด <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-tl/strings.xml b/go/res/values-tl/strings.xml new file mode 100644 index 000000000..8f44ec574 --- /dev/null +++ b/go/res/values-tl/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Pindutin nang matagal upang kumuha ng shortcut."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"I-double tap nang matagal upang kumuha ng shortcut o gumamit ng mga custom na pagkilos."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Mga Shortcut"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Mga shortcut sa <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-tr/strings.xml b/go/res/values-tr/strings.xml new file mode 100644 index 000000000..f0f3cce6d --- /dev/null +++ b/go/res/values-tr/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Kısayol seçmek için dokunun ve basılı tutun."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Kısayollar"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> kısayolları"</string> +</resources> diff --git a/go/res/values-uk/strings.xml b/go/res/values-uk/strings.xml new file mode 100644 index 000000000..8d1f58395 --- /dev/null +++ b/go/res/values-uk/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Натисніть і утримуйте, щоб вибрати ярлик."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Двічі натисніть і утримуйте, щоб вибрати ярлик, або виконайте іншу дію."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Ярлики"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Ярлики додатка <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-ur/strings.xml b/go/res/values-ur/strings.xml new file mode 100644 index 000000000..46bd823d8 --- /dev/null +++ b/go/res/values-ur/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"کوئی شارٹ کٹ منتخب کرنے کیلئے ٹچ کریں اور دبائے رکھیں۔"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"کوئی شارٹ کٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔"</string> + <string name="widget_button_text" msgid="4221900832360456858">"شارٹ کٹس"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> شارٹ کٹس"</string> +</resources> diff --git a/go/res/values-uz-rUZ/strings.xml b/go/res/values-uz-rUZ/strings.xml new file mode 100644 index 000000000..318bc1572 --- /dev/null +++ b/go/res/values-uz-rUZ/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Yorliqni tanlab olish uchun bosib turing."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Yorliqlar"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi yorliqlari"</string> +</resources> diff --git a/go/res/values-uz/strings.xml b/go/res/values-uz/strings.xml new file mode 100644 index 000000000..318bc1572 --- /dev/null +++ b/go/res/values-uz/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Yorliqni tanlab olish uchun bosib turing."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Yorliqlar"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi yorliqlari"</string> +</resources> diff --git a/go/res/values-vi/strings.xml b/go/res/values-vi/strings.xml new file mode 100644 index 000000000..1197619c5 --- /dev/null +++ b/go/res/values-vi/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Chạm và giữ để chọn lối tắt."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Lối tắt"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Lối tắt <xliff:g id="NAME">%1$s</xliff:g>"</string> +</resources> diff --git a/go/res/values-zh-rCN/strings.xml b/go/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..57351d37f --- /dev/null +++ b/go/res/values-zh-rCN/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"触摸并按住快捷方式即可选择快捷方式。"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"点按两次并按住快捷方式即可选择快捷方式,您也可以使用自定义操作。"</string> + <string name="widget_button_text" msgid="4221900832360456858">"快捷方式"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>快捷方式"</string> +</resources> diff --git a/go/res/values-zh-rHK/strings.xml b/go/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000..dea7749f6 --- /dev/null +++ b/go/res/values-zh-rHK/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"按住捷徑即可選取捷徑。"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"扲兩下然後扲住就可以揀選捷徑,或者用自訂嘅操作。"</string> + <string name="widget_button_text" msgid="4221900832360456858">"捷徑"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> 捷徑"</string> +</resources> diff --git a/go/res/values-zh-rTW/strings.xml b/go/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..07ae2ed5b --- /dev/null +++ b/go/res/values-zh-rTW/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"按住捷徑即可選取。"</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"輕觸兩下並按住捷徑即可選取,你也可以使用自訂動作。"</string> + <string name="widget_button_text" msgid="4221900832360456858">"捷徑"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"「<xliff:g id="NAME">%1$s</xliff:g>」捷徑"</string> +</resources> diff --git a/go/res/values-zu/strings.xml b/go/res/values-zu/strings.xml new file mode 100644 index 000000000..e5051df1f --- /dev/null +++ b/go/res/values-zu/strings.xml @@ -0,0 +1,26 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="long_press_widget_to_add" msgid="4001616142797446267">"Thinta futhi ubambe ukuze ukhethe isinqamuleli."</string> + <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Thepha kabulu futhi ubambe ukuze ukhethe isinqamuleli noma usebenzise izenzo zangokwezifiso."</string> + <string name="widget_button_text" msgid="4221900832360456858">"Izinqamuleli"</string> + <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> izinqamuleli"</string> +</resources> diff --git a/go/res/values/strings.xml b/go/res/values/strings.xml new file mode 100644 index 000000000..8ef2e6243 --- /dev/null +++ b/go/res/values/strings.xml @@ -0,0 +1,33 @@ +<?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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Message to tell the user to press and hold on a shortcut to add it [CHAR_LIMIT=50] --> + <string name="long_press_widget_to_add">Touch & hold to pick up a shortcut.</string> + <!-- Accessibility spoken hint message in widget picker, which allows user to add a shortcut. Custom action is the label for additional accessibility actions available in this mode [CHAR_LIMIT=100] --> + <string name="long_accessible_way_to_add">Double-tap & hold to pick up a shortcut or use custom actions.</string> + <!-- Text for shortcut add button --> + <string name="widget_button_text">Shortcuts</string> + + <!-- Strings for widgets & more in the popup container/bottom sheet --> + <!-- Title for a bottom sheet that shows shortcuts for a particular app --> + <string name="widgets_bottom_sheet_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> shortcuts</string> + +</resources> diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml new file mode 100644 index 000000000..094fc745c --- /dev/null +++ b/go/res/xml/device_profiles.xml @@ -0,0 +1,33 @@ +<?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. +--> + +<profiles xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" > + + <profile + launcher:name="Go Device" + launcher:minWidthDps="296" + launcher:minHeightDps="491.33" + launcher:numRows="4" + launcher:numColumns="4" + launcher:numFolderRows="4" + launcher:numFolderColumns="4" + launcher:iconSize="56" + launcher:iconTextSize="14.0" + launcher:defaultLayoutId="@xml/default_workspace_4x4" + /> + +</profiles>
\ No newline at end of file diff --git a/go/src_flags/com/android/launcher3/config/FeatureFlags.java b/go/src_flags/com/android/launcher3/config/FeatureFlags.java new file mode 100644 index 000000000..b11bb7c6a --- /dev/null +++ b/go/src_flags/com/android/launcher3/config/FeatureFlags.java @@ -0,0 +1,29 @@ +/* + * 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.config; + +/** + * Defines a set of flags used to control various launcher behaviors + */ +public final class FeatureFlags extends BaseFlags { + + private FeatureFlags() {} + + // Features to control Launcher3Go behavior + public static final boolean GO_DISABLE_WIDGETS = true; + public static final boolean LAUNCHER3_SPRING_ICONS = false; +} diff --git a/proto_overrides/launcher_log_extension.proto b/proto_overrides/launcher_log_extension.proto new file mode 100644 index 000000000..2995aa283 --- /dev/null +++ b/proto_overrides/launcher_log_extension.proto @@ -0,0 +1,30 @@ +/* + * 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. + */ +syntax = "proto2"; + +option java_package = "com.android.launcher3.userevent"; +option java_outer_classname = "LauncherLogExtensions"; + +package userevent; + +// +// Use this to add any app specific extensions to the proto. +// +message LauncherEventExtension { +} + +message TargetExtension { +} diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto index 93e09aea8..0bbec188d 100644 --- a/protos/launcher_log.proto +++ b/protos/launcher_log.proto @@ -15,6 +15,8 @@ */ syntax = "proto2"; +import "launcher_log_extension.proto"; + option java_package = "com.android.launcher3.userevent"; option java_outer_classname = "LauncherLogProto"; @@ -52,6 +54,7 @@ message Target { optional int32 span_x = 13 [default = 1];// Used for ItemType.WIDGET optional int32 span_y = 14 [default = 1];// Used for ItemType.WIDGET optional int32 predictedRank = 15; + optional TargetExtension extension = 16; } // Used to define what type of item a Target would represent. @@ -144,7 +147,6 @@ message Action { // Action (Touch) + Target + Target // message LauncherEvent { - required Action action = 1; // List of targets that touch actions can be operated on. @@ -157,4 +159,6 @@ message LauncherEvent { optional bool is_in_multi_window_mode = 7; optional bool is_in_landscape_mode = 8; + + optional LauncherEventExtension extension = 9; } diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 4acc49deb..d71b4c78b 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Raak en hou om self te plaas"</string> <string name="place_automatically" msgid="8064208734425456485">"Voeg outomaties by"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Deursoek programme"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Laai tans programme …"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Geen programme gevind wat met \"<xliff:g id="QUERY">%1$s</xliff:g>\" ooreenstem nie"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Deursoek programme"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string> <string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string> <string name="out_of_space" msgid="4691004494942118364">"Niks meer spasie op die tuisskerm nie."</string> diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index 0f795b33a..293b452f6 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"መተግበሪያዎችን ፈልግ"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"መተግበሪያዎችን በመጫን ላይ…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"ከ«<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> diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 0177166ea..6447bf015 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"بحث في التطبيقات"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"جارٍ تحميل التطبيقات…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"لم يتم العثور على أي تطبيقات تتطابق مع \"<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> diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 6b50e4dae..18f87bcf3 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Tətbiqləri axtarın"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Tətbiqlər yüklənir…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq 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> diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index d73b86f1b..777512a96 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"širina od %1$d i visina od %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite da biste postavili ručno"</string> <string name="place_automatically" msgid="8064208734425456485">"Automatski dodaj"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretražite 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 za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži još aplikacija"</string> <string name="notifications_header" msgid="1404149926117359025">"Obaveštenja"</string> <string name="out_of_space" msgid="4691004494942118364">"Nema više prostora na ovom početnom ekranu."</string> diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index b2ec14369..0a31ddf7c 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Пошук праграм"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Праграмы загружаюцца…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Праграм, якія адпавядаюць запыту \"<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> diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 89feb3580..3e05e0be5 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Търсене в приложенията"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Приложенията се зареждат…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Няма намерени приложения, съответстващи на „<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> diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 02a95f236..471602f47 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -27,7 +27,7 @@ <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="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> @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"অ্যাপ অনুসন্ধান করুন"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"অ্যাপ লোড হচ্ছে…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> @@ -60,7 +60,7 @@ <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_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> diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 10cf2f960..49c862a8c 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za upit \"<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> diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 6a4fbc2cd..b1a1f85e0 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toca i mantén premut l\'element per col·locar-lo manualment"</string> <string name="place_automatically" msgid="8064208734425456485">"Afegeix automàticament"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cerca a les aplicacions"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"S\'estan carregant les aplicacions..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"No s\'ha trobat cap aplicació que coincideixi amb <xliff:g id="QUERY">%1$s</xliff:g>"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca aplicacions"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"S\'estan carregant les aplicacions…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string> <string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string> <string name="out_of_space" msgid="4691004494942118364">"Ja no queda espai en aquesta pantalla d\'inici."</string> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index c1daed95a..e6dee3c3b 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chcete-li položku umístit ručně, klepněte na ni a podržte ji"</string> <string name="place_automatically" msgid="8064208734425456485">"Přidat automaticky"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Hledat aplikace"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Načítání aplikací…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hledat v aplikacích"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítání aplikací…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Vyhledat další aplikace"</string> <string name="notifications_header" msgid="1404149926117359025">"Oznámení"</string> <string name="out_of_space" msgid="4691004494942118364">"Na této ploše již není místo."</string> @@ -76,11 +76,11 @@ <string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string> <string name="allow_rotation_desc" msgid="8662546029078692509">"Při otočení telefonu"</string> <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuální nastavení displeje neumožňuje otáčení"</string> - <string name="icon_badging_title" msgid="874121399231955394">"Puntíky s oznámeními"</string> + <string name="icon_badging_title" msgid="874121399231955394">"Puntíky s oznámením"</string> <string name="icon_badging_desc_on" msgid="2627952638544674079">"Zapnuto"</string> <string name="icon_badging_desc_off" msgid="5503319969924580241">"Vypnuto"</string> <string name="title_missing_notification_access" msgid="7503287056163941064">"Je třeba udělit přístup k oznámením"</string> - <string name="msg_missing_notification_access" msgid="281113995110910548">"Chcete-li zobrazovat puntíky s oznámeními, zapněte oznámení z aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string> + <string name="msg_missing_notification_access" msgid="281113995110910548">"Chcete-li zobrazovat puntíky s oznámením, zapněte oznámení z aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="title_change_settings" msgid="1376365968844349552">"Změnit nastavení"</string> <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Přidat ikonu na plochu"</string> <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pro nové aplikace"</string> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 2e6200907..653105e05 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tryk, og hold fingeren nede for at placere manuelt"</string> <string name="place_automatically" msgid="8064208734425456485">"Tilføj automatisk"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Søg i Apps"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Indlæser apps…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Indlæser apps…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søg efter flere apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Underretninger"</string> <string name="out_of_space" msgid="4691004494942118364">"Der er ikke mere plads på denne startskærm."</string> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index ec94408f6..1c4cd7a7c 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Zum manuellen Hinzufügen gedrückt halten"</string> <string name="place_automatically" msgid="8064208734425456485">"Automatisch hinzufügen"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"In Apps suchen"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Apps werden geladen..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps finden"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps werden geladen…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Weitere Apps suchen"</string> <string name="notifications_header" msgid="1404149926117359025">"Benachrichtigungen"</string> <string name="out_of_space" msgid="4691004494942118364">"Auf diesem Startbildschirm ist kein Platz mehr vorhanden."</string> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 49c0fc61c..25c8866b8 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Αναζήτηση εφαρμογών"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Φόρτωση εφαρμογών…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"<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> diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 207791266..f3f10cc82 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch & hold to place manually"</string> <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string> <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string> diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 207791266..f3f10cc82 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch & hold to place manually"</string> <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string> <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string> diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 207791266..f3f10cc82 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch & hold to place manually"</string> <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string> <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 4054a4282..f60e1862a 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén presionado para ubicarlo manualmente"</string> <string name="place_automatically" msgid="8064208734425456485">"Agregar automáticamente"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Buscar aplicaciones"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicaciones…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"No hay aplicaciones que coincidan con <xliff:g id="QUERY">%1$s</xliff:g>."</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar apps"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando apps…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"No hay apps que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string> <string name="out_of_space" msgid="4691004494942118364">"No hay más espacio en esta pantalla principal."</string> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 70addf7aa..3ab41caf6 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantenlo pulsado para añadirlo manualmente"</string> <string name="place_automatically" msgid="8064208734425456485">"Añadir automáticamente"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Busca aplicaciones"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicaciones…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicaciones"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicaciones…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string> <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string> <string name="out_of_space" msgid="4691004494942118364">"No queda espacio en la pantalla de inicio."</string> diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 28daf6c71..9d9991ddc 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Otsige rakendusi"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Rakenduste laadimine …"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"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> diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 09a5f8438..b6082fada 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Bilatu aplikazioetan"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikazioak kargatzen…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</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> diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 4d116a2f2..8fe874b32 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"جستجوی برنامهها"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامهها…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"هیچ برنامهای در مطابقت با «<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> diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index d44e88685..016dbbce3 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sijoita manuaalisesti koskettamalla pitkään."</string> <string name="place_automatically" msgid="8064208734425456485">"Lisää automaattisesti"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sovellushaku"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Ladataan sovelluksia…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"”<xliff:g id="QUERY">%1$s</xliff:g>” ei palauttanut sovelluksia."</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hae sovelluksia"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Ladataan sovelluksia…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string> <string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string> <string name="out_of_space" msgid="4691004494942118364">"Tässä aloitusruudussa ei ole enää tilaa."</string> diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index e76954cf1..e57433d0c 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Maintenez le doigt sur l\'élément pour le placer manuellement"</string> <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Rechercher des applications"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Chargement des applications en cours..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications en cours…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string> <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur l\'écran d\'accueil."</string> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index b82d7fc1d..dde439288 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Appuyez de manière prolongée pour placer l\'élément manuellement"</string> <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Rechercher dans les applications"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Chargement des applications en cours…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\"."</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string> <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur cet écran d\'accueil."</string> diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 4be320398..d55514d1e 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Buscar aplicacións"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicacións…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"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> diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 587d16eb4..7096a3ee0 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -29,15 +29,15 @@ <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_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_bar_hint" msgid="1390553134053255246">"શોધ ઍપ્લિકેશનો"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> @@ -72,7 +72,7 @@ <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string> <string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ્સ"</string> <string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string> - <string name="accessibility_action_overview" msgid="6257665857640347026">"વિહંગાવલોકન"</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> diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 16eefa754..f1ee0f236 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ऐप्लिकेशन खोजें"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> @@ -72,7 +72,7 @@ <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string> <string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग"</string> <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके व्यवस्थापक द्वारा अक्षम"</string> - <string name="accessibility_action_overview" msgid="6257665857640347026">"अवलोकन"</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> diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 01b28f140..aaae258b8 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite stavku da biste je postavili 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">"Učitavanje aplikacija…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretraži aplikacije"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Učitavanje aplikacija…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Traži više aplikacija"</string> <string name="notifications_header" msgid="1404149926117359025">"Obavijesti"</string> <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom zaslonu više nema mjesta."</string> diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 68c2a6c3e..2da64b06b 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tartsa lenyomva a manuális hozzáadáshoz"</string> <string name="place_automatically" msgid="8064208734425456485">"Automatikus hozzáadás"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Alkalmazások keresése"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Alkalmazások betöltése…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Egy alkalmazás sem található a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre."</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Alkalmazások keresése"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Alkalmazások betöltése…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string> <string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string> <string name="out_of_space" msgid="4691004494942118364">"Nincs több hely ezen a kezdőképernyőn."</string> diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 413f51fb3..2b55e966a 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Որոնել հավելվածներ"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Հավելվածների բեռնում…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"«<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> diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index af84cfc45..379a960d0 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh & tahan untuk menempatkan secara manual"</string> <string name="place_automatically" msgid="8064208734425456485">"Tambahkan otomatis"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Telusuri Apps"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Memuat Aplikasi..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Tidak ditemukan Aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string> <string name="out_of_space" msgid="4691004494942118364">"Tidak ada ruang lagi pada layar Utama ini."</string> diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 3c54fc2e4..cf178a56a 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Leita í forritum"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Hleður forrit…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"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> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 7e062f304..a52aee429 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tieni premuto per posizionare l\'elemento manualmente"</string> <string name="place_automatically" msgid="8064208734425456485">"Aggiungi automaticamente"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cerca app"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Caricamento di app…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca nelle app"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Caricamento delle app…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string> <string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string> <string name="out_of_space" msgid="4691004494942118364">"Spazio nella schermata Home esaurito."</string> diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index eb0084653..650a90db8 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"חיפוש אפליקציות"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"טוען אפליקציות…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"לא נמצאו אפליקציות התואמות ל-\"<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> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 2859ca8f2..4071a6cc9 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"アプリを検索"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"アプリを読み込んでいます…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"「<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> diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 12171083f..7e8b46ce8 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"აპების ძიება"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"აპები იტვირთება…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"„<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> diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 6cb4fa74e..50ed9aa68 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Қолданбаларды іздеу"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Қолданбалар жүктелуде…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 8782230bb..7028f7e3a 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ស្វែងរកកម្មវិធី"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"កំពុងផ្ទុកកម្មវិធី…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"រកមិនឃើញកម្មវិធីដែលត្រូវគ្នាជាមួយ \"<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> diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 7566503b0..9a31649be 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 9926d4f92..e3511d441 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"앱 검색"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"앱 로드 중…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\'<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> diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 7d19b3031..85ba8be3c 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index e31584d2e..9a50c4b51 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ຊອກຫາແອັບ"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ກໍາລັງໂຫຼດແອັບ…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"ບໍ່ພົບແອັບທີ່ກົງກັບ \"<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> diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index cbd6048e2..d415e4df1 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Palieskite ir palaikykite, kad padėtumėte patys"</string> <string name="place_automatically" msgid="8064208734425456485">"Pridėti automatiškai"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Ieškoti programų"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Įkeliamos programos..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Paieškos programos"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Įkeliamos programos…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Ieškoti daugiau programų"</string> <string name="notifications_header" msgid="1404149926117359025">"Pranešimai"</string> <string name="out_of_space" msgid="4691004494942118364">"Šiame pagrindiniame ekrane vietos nebėra."</string> diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 6411dc882..2d8bfd83a 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pieskarieties un turiet, lai manuāli pievienotu"</string> <string name="place_automatically" msgid="8064208734425456485">"Pievienot automātiski"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Meklēt lietotnes"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Notiek lietotņu ielāde…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne."</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Meklēt lietotnes"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Notiek lietotņu ielāde…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Meklēt citas lietotnes"</string> <string name="notifications_header" msgid="1404149926117359025">"Paziņojumi"</string> <string name="out_of_space" msgid="4691004494942118364">"Šajā sākuma ekrānā vairs nav vietas."</string> diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 1061ebf20..7d95a23a6 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Пребарувајте апликации"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Се вчитуваат апликации…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Не се најдени апликации што одговараат на „<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> diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 62bcc8cbe..0cc7aa023 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ആപ്പുകൾ തിരയുക"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> @@ -72,7 +72,7 @@ <string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string> <string name="settings_button_text" msgid="8873672322605444408">"ഹോം ക്രമീകരണം"</string> <string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string> - <string name="accessibility_action_overview" msgid="6257665857640347026">"കാഴ്ച"</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> diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index b35057064..22479cc3e 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Апп хайх"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачааллаж байна..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 3435061b8..751ad227a 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -27,31 +27,31 @@ <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="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="place_automatically" msgid="8064208734425456485">"अापोआप जोडा"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अॅप्स शोधा"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"अॅप्स लोड करत आहे…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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="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="permlab_read_settings" msgid="1941457408239617576">"होम सेटिग्ज आणि शॉर्टकट वाचा"</string> <string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."</string> - <string name="permlab_write_settings" msgid="3574213698004620587">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट लिहा"</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> @@ -72,7 +72,7 @@ <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string> <string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग्ज"</string> <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string> - <string name="accessibility_action_overview" msgid="6257665857640347026">"विहंगावलोकन"</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> @@ -82,7 +82,7 @@ <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचनांच्या अॅक्सेसची आवश्यकता आहे"</string> <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदू दाखवण्यासाठी, <xliff:g id="NAME">%1$s</xliff:g> साठी अॅप सूचना चालू करा"</string> <string name="title_change_settings" msgid="1376365968844349552">"सेटिंग्ज बदला"</string> - <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"मुख्य स्क्रीनवर चिन्ह जोडा"</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_system_default" msgid="1709762974822753030">"सिस्टमचे डीफॉल्ट वापरा"</string> @@ -99,7 +99,7 @@ <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_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> diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 0dfe81af7..f94b167a6 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -35,9 +35,9 @@ <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 & 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_bar_hint" msgid="1390553134053255246">"Cari apl"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuatkan apl…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"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> diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 3d1311f55..74574b9b2 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ရှာဖွေမှု အက်ပ်များ"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"အက်ပ်များကို ဖွင့်နေသည်…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 550345145..65247c168 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Trykk og hold for å plassere manuelt"</string> <string name="place_automatically" msgid="8064208734425456485">"Legg til automatisk"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Søk i apper"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Laster inn apper …"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søk etter apper"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Laster inn appene …"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søk etter flere apper"</string> <string name="notifications_header" msgid="1404149926117359025">"Varsler"</string> <string name="out_of_space" msgid="4691004494942118364">"Denne startsiden er full."</string> diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index b28e0e2b4..904dad45e 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी अनुप्रयोगहरू"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"अनुप्रयोगहरू लोड गर्दै…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 42871aba2..7e8def4ca 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tik op een item en houd dit vast om het handmatig te plaatsen"</string> <string name="place_automatically" msgid="8064208734425456485">"Automatisch toevoegen"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Apps zoeken"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Apps laden…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps zoeken"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps laden…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Zoeken naar meer apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Meldingen"</string> <string name="out_of_space" msgid="4691004494942118364">"Er is geen ruimte meer op dit startscherm."</string> diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index aaf4c92cb..cf5351c7a 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -25,7 +25,7 @@ <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="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> @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ਐਪਾਂ ਖੋਜੋ"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> @@ -68,7 +68,7 @@ <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="widget_button_text" msgid="2880537293434387943">"ਵਿਜੇਟ"</string> <string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string> <string name="settings_button_text" msgid="8873672322605444408">"ਹੋਮ ਸੈਟਿੰਗਾਂ"</string> <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string> @@ -98,7 +98,7 @@ <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="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> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 8edcd9971..c07f7defb 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Kliknij i przytrzymaj, by umieścić ręcznie"</string> <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatycznie"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Szukaj w aplikacjach"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Wczytuję aplikacje…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Wyszukaj aplikacje"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Ładuję aplikacje…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Wyszukaj więcej aplikacji"</string> <string name="notifications_header" msgid="1404149926117359025">"Powiadomienia"</string> <string name="out_of_space" msgid="4691004494942118364">"Brak miejsca na tym ekranie głównym."</string> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index f6ca7b415..100f07b66 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque sem soltar para colocar manualmente"</string> <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pesquisar aplicações"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"A carregar aplicações..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Não foram encontradas aplic. que correspondam a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar aplicações"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"A carregar aplicações…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma aplicação correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais aplicações"</string> <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string> <string name="out_of_space" msgid="4691004494942118364">"Sem espaço suficiente neste Ecrã principal."</string> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 11bfc020c..d75159f94 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque e mantenha pressionado para posicionar manualmente"</string> <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pesquisar apps"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Carregando apps…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps de pesquisa"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string> <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string> <string name="out_of_space" msgid="4691004494942118364">"Não há mais espaço na tela inicial."</string> diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 27e23b2ff..512d96d6b 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Atingeți lung pentru a plasa manual"</string> <string name="place_automatically" msgid="8064208734425456485">"Adăugați automat"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Căutați aplicații"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Se încarcă aplicațiile..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>”"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Căutați aplicații"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Se încarcă aplicații…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Căutați mai multe aplicații"</string> <string name="notifications_header" msgid="1404149926117359025">"Notificări"</string> <string name="out_of_space" msgid="4691004494942118364">"Nu mai este loc pe acest Ecran de pornire."</string> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 06278925b..923f3573b 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Поиск приложений"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Загрузка приложений…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"По запросу \"<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> diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index fcb3bc0a7..f6c42b2d9 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"යෙදුම් සොයන්න"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"යෙදුම් පූරණය වෙමින්…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 7df18cbf7..4dbc407b9 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Položku umiestnite ručne klepnutím a podržaním"</string> <string name="place_automatically" msgid="8064208734425456485">"Pridať automaticky"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Hľadať aplikácie"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Načítavajú sa aplikácie..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hľadať aplikácie"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítavajú sa aplikácie…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hľadať ďalšie aplikácie"</string> <string name="notifications_header" msgid="1404149926117359025">"Upozornenia"</string> <string name="out_of_space" msgid="4691004494942118364">"Na tejto ploche už nie je miesto"</string> @@ -58,7 +58,7 @@ <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavenie"</string> <string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikácia a nedá sa odinštalovať."</string> <string name="folder_hint_text" msgid="6617836969016293992">"Nepomenovaný priečinok"</string> - <string name="disabled_app_label" msgid="6673129024321402780">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je zakázaná"</string> + <string name="disabled_app_label" msgid="6673129024321402780">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je deaktivovaná"</string> <string name="default_scroll_format" msgid="7475544710230993317">"Stránka %1$d z %2$d"</string> <string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string> <string name="workspace_new_page" msgid="257366611030256142">"Nová stránka plochy"</string> diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 06e761e86..0b7d36ef8 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dotaknite se elementa in ga pridržite, da ga ročno dodate"</string> <string name="place_automatically" msgid="8064208734425456485">"Samodejno dodaj"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Iskanje po aplikacijah"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Nalaganje aplikacij …"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Iskanje programov"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Nalaganje aplikacij …"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Iskanje več aplikacij"</string> <string name="notifications_header" msgid="1404149926117359025">"Obvestila"</string> <string name="out_of_space" msgid="4691004494942118364">"Na tem začetnem zaslonu ni več prostora."</string> diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 4ec5dc1ad..3e6afee60 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Kërko për aplikacione"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Po ngarkon aplikacionet..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"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> diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index aa907ebc6..f41e02d33 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Претражите апликације"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Апликације се учитавају…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Није пронађена ниједна апликација за „<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> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 5eb791446..6c598ff5d 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Placera manuellt genom att trycka länge"</string> <string name="place_automatically" msgid="8064208734425456485">"Lägg till automatiskt"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sök efter appar"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Läser in appar …"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Det gick inte att hitta några appar som matchar <xliff:g id="QUERY">%1$s</xliff:g>"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sök efter appar"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Läser in appar …"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Inga appar som matchar <xliff:g id="QUERY">%1$s</xliff:g> hittades"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sök efter fler appar"</string> <string name="notifications_header" msgid="1404149926117359025">"Aviseringar"</string> <string name="out_of_space" msgid="4691004494942118364">"Det finns inte plats för mer på den här startskärmen."</string> diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index a77360045..3de28e011 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Gusa na ushikilie ili uweke mwenyewe"</string> <string name="place_automatically" msgid="8064208734425456485">"Ongeza kiotomatiki"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tafuta Programu"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Inapakia Programu..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Haikupata programu zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tafuta programu"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Inapakia programu..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Haikupata programu zozote zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tafuta programu zaidi"</string> <string name="notifications_header" msgid="1404149926117359025">"Arifa"</string> <string name="out_of_space" msgid="4691004494942118364">"Hakuna nafasi katika skrini hii ya Mwanzo."</string> diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 156a49e37..1d92581a0 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"பயன்பாடுகளில் தேடுக"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"பயன்பாடுகளை ஏற்றுகிறது…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 94e09d866..6c6669938 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -22,9 +22,9 @@ <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="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> @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %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_bar_hint" msgid="1390553134053255246">"అప్లికేషన్లను శోధించండి"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్లను లోడ్ చేస్తోంది…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> @@ -56,7 +56,7 @@ <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="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> @@ -94,8 +94,8 @@ <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="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> diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 4eb342f41..b37009988 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ค้นหาแอป"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"กำลังโหลดแอป…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"ไม่พบแอปที่ตรงกับ \"<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> diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 0a26793dc..54135c9d5 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pindutin nang matagal upang manual na ilagay"</string> <string name="place_automatically" msgid="8064208734425456485">"Awtomatikong idagdag"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Mga App sa Paghahanap"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Nilo-load ang Mga App…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Walang nakitang Mga App na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Maghanap ng mga app"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Naglo-load ng mga app…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Walang nahanap na app na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Maghanap ng higit pang mga app"</string> <string name="notifications_header" msgid="1404149926117359025">"Mga Notification"</string> <string name="out_of_space" msgid="4691004494942118364">"Wala nang lugar sa Home screen na ito."</string> diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 1b6a2a047..cb8b50af2 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manuel olarak yerleştirmek için dokunun ve basılı tutun"</string> <string name="place_automatically" msgid="8064208734425456485">"Otomatik olarak ekle"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Uygulamalarda Ara"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Uygulamalar Yükleniyor…"</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Uygulamalarda ara"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Uygulamalar yükleniyor…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Başka uygulamalar ara"</string> <string name="notifications_header" msgid="1404149926117359025">"Bildirimler"</string> <string name="out_of_space" msgid="4691004494942118364">"Bu Ana ekranda yer kalmadı."</string> diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 52224f322..a9e010921 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Пошук додатків"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Завантаження додатків…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Немає додатків для запиту \"<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> diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index f3d6d3f3c..a704fab4c 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"ایپس تلاش کریں"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"ایپس لوڈ کی جا رہی ہیں…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<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> diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index aa288560c..7e3188913 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"Ilovalarni qidirish"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilovalar yuklanmoqda…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"“<xliff:g id="QUERY">%1$s</xliff:g>” bilan mos hech qanday ilova 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> diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 93f96c31c..83e1ceaba 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chạm và giữ để đặt theo cách thủ công"</string> <string name="place_automatically" msgid="8064208734425456485">"Tự động thêm"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tìm kiếm ứng dụng"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Đang tải ứng dụng..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tìm kiếm ứng dụng"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Đang tải ứng dụng…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tìm kiếm thêm ứng dụng"</string> <string name="notifications_header" msgid="1404149926117359025">"Thông báo"</string> <string name="out_of_space" msgid="4691004494942118364">"Không còn chỗ trên Màn hình chính này."</string> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 00f0b16db..bef12fb61 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"搜索应用"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"正在加载应用…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"未找到与“<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> diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index b8ebf8f66..7ac555395 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<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> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 9640fb8e1..e0c4c9973 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -35,9 +35,9 @@ <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_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<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> diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index f1ea49e5f..ef6fdeb10 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -35,9 +35,9 @@ <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string> <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Thinta futhi ubambe ukuze ubeke ngokwenza"</string> <string name="place_automatically" msgid="8064208734425456485">"Engeza ngokuzenzakalelayo"</string> - <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sesha Izinhlelo Zokusebenza"</string> - <string name="all_apps_loading_message" msgid="7557140873644765180">"Ilayisha izinhlelo zokusebenza..."</string> - <string name="all_apps_no_search_results" msgid="6332185285860416787">"Azikho izinhlelo zokusebenza ezitholakele ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> + <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sesha izinhlelo zokusebenza"</string> + <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string> + <string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string> <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sesha izinhlelo zokusebenza eziningi"</string> <string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string> <string name="out_of_space" msgid="4691004494942118364">"Asisekho isikhala kulesi sikrini Sasekhaya."</string> diff --git a/res/values/config.xml b/res/values/config.xml index e9c62a783..e7ec0a0b1 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -9,6 +9,8 @@ <bool name="is_large_tablet">false</bool> <bool name="allow_rotation">false</bool> + <integer name="extracted_color_gradient_alpha">191</integer> + <!-- A string pointer to the original app name string. This allows derived projects to easily override the app name without providing all translations --> <string name="derived_app_name" translatable="false">@string/app_name</string> diff --git a/res/values/strings.xml b/res/values/strings.xml index 99296717a..1197b1cf2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -59,11 +59,11 @@ <!-- All Apps --> <!-- Search bar text in the apps view. [CHAR_LIMIT=50] --> - <string name="all_apps_search_bar_hint">Search Apps</string> + <string name="all_apps_search_bar_hint">Search apps</string> <!-- Loading apps text. [CHAR_LIMIT=50] --> - <string name="all_apps_loading_message">Loading Apps…</string> + <string name="all_apps_loading_message">Loading apps…</string> <!-- No-search-results text. [CHAR_LIMIT=50] --> - <string name="all_apps_no_search_results">No Apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string> + <string name="all_apps_no_search_results">No apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string> <!-- Label for the button which allows the user to get app search results. [CHAR_LIMIT=50] --> <string name="all_apps_search_market_message">Search for more apps</string> diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java index 6e33d2a55..b249c9530 100644 --- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java +++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java @@ -13,6 +13,7 @@ import android.support.annotation.WorkerThread; import android.util.Log; import com.android.launcher3.LauncherSettings.Favorites; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.LoaderTask; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.util.ContentWriter; @@ -26,7 +27,7 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) { int hostId = intent.getIntExtra(AppWidgetManager.EXTRA_HOST_ID, 0); Log.d(TAG, "Widget ID map received for host:" + hostId); - if (hostId != Launcher.APPWIDGET_HOST_ID) { + if (hostId != LauncherAppWidgetHost.APPWIDGET_HOST_ID) { return; } @@ -38,7 +39,8 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { .postAtFrontOfQueue(new Runnable() { @Override public void run() { - restoreAppWidgetIds(context, asyncResult, oldIds, newIds); + restoreAppWidgetIds(context, oldIds, newIds); + asyncResult.finish(); } }); } else { @@ -51,9 +53,13 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { * Updates the app widgets whose id has changed during the restore process. */ @WorkerThread - static void restoreAppWidgetIds(Context context, PendingResult asyncResult, - int[] oldWidgetIds, int[] newWidgetIds) { - AppWidgetHost appWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID); + static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) { + AppWidgetHost appWidgetHost = new LauncherAppWidgetHost(context); + if (FeatureFlags.GO_DISABLE_WIDGETS) { + Log.e(TAG, "Skipping widget ID remap as widgets not supported"); + appWidgetHost.deleteHost(); + return; + } if (!RestoreDbTask.isPending(context)) { // Someone has already gone through our DB once, probably LoaderTask. Skip any further // modifications of the DB. @@ -62,7 +68,6 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { Log.d(TAG, "Deleting widgetId: " + widgetId); appWidgetHost.deleteAppWidgetId(widgetId); } - asyncResult.finish(); return; } final ContentResolver cr = context.getContentResolver(); @@ -106,6 +111,5 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { if (app != null) { app.getModel().forceReload(); } - asyncResult.finish(); } } diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 2b59ede47..e49649502 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -19,6 +19,7 @@ package com.android.launcher3; import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; +import android.content.Intent; import android.view.View.AccessibilityDelegate; import com.android.launcher3.logging.UserEventDispatcher; @@ -63,4 +64,9 @@ public abstract class BaseActivity extends Activity { } return mSystemUiController; } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + } } diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index aac80052e..3ebccda9e 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -780,7 +780,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { return mCellWidth; } - int getCellHeight() { + public int getCellHeight() { return mCellHeight; } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 60c19bc5d..150bc5309 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -365,7 +365,7 @@ public class DeviceProfile { if (isVerticalBarLayout()) { hotseatBarSizePx = iconSizePx; } - hotseatCellHeightPx = iconSizePx + iconDrawablePaddingPx; + hotseatCellHeightPx = iconSizePx; if (!isVerticalBarLayout()) { int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 3ae4316a9..615ec4716 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -144,6 +144,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.Executor; /** * Default launcher application. @@ -209,10 +210,8 @@ public class Launcher extends BaseActivity private boolean mIsSafeModeEnabled; - public static final int APPWIDGET_HOST_ID = 1024; public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 500; private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500; - private static final int ACTIVITY_START_DELAY = 1000; // How long to wait before the new-shortcut animation automatically pans the workspace private static final int NEW_APPS_PAGE_MOVE_DELAY = 500; @@ -397,7 +396,10 @@ public class Launcher extends BaseActivity mAppWidgetManager = AppWidgetManagerCompat.getInstance(this); - mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID); + mAppWidgetHost = new LauncherAppWidgetHost(this); + if (Utilities.ATLEAST_MARSHMALLOW) { + mAppWidgetHost.addProviderChangeListener(this); + } mAppWidgetHost.startListening(); // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here, @@ -789,7 +791,7 @@ public class Launcher extends BaseActivity } @Override - protected void onActivityResult( + public void onActivityResult( final int requestCode, final int resultCode, final Intent data) { handleActivityResult(requestCode, resultCode, data); if (mLauncherCallbacks != null) { @@ -1468,23 +1470,25 @@ public class Launcher extends BaseActivity mWorkspace.addInScreen(view, info); } else { // Adding a shortcut to a Folder. - final long folderIconId = container; - FolderIcon folderIcon = (FolderIcon) mWorkspace.getFirstMatch(new ItemOperator() { - @Override - public boolean evaluate(ItemInfo info, View view) { - return info != null && info.id == folderIconId; - } - }); - + FolderIcon folderIcon = findFolderIcon(container); if (folderIcon != null) { FolderInfo folderInfo = (FolderInfo) folderIcon.getTag(); folderInfo.add(info, args.rank, false); } else { - Log.e(TAG, "Could not find folder with id " + folderIconId + " to add shortcut."); + Log.e(TAG, "Could not find folder with id " + container + " to add shortcut."); } } } + public FolderIcon findFolderIcon(final long folderIconId) { + return (FolderIcon) mWorkspace.getFirstMatch(new ItemOperator() { + @Override + public boolean evaluate(ItemInfo info, View view) { + return info != null && info.id == folderIconId; + } + }); + } + /** * Add a widget to the workspace. * @@ -1852,6 +1856,8 @@ public class Launcher extends BaseActivity LauncherAnimUtils.onDestroyActivity(); + clearPendingBinds(); + if (mLauncherCallbacks != null) { mLauncherCallbacks.onDestroy(); } @@ -3702,6 +3708,13 @@ public class Launcher extends BaseActivity } if (mAppsView != null) { + Executor pendingExecutor = getPendingExecutor(); + if (pendingExecutor != null && mState != State.APPS) { + // Wait until the fade in animation has finished before setting all apps list. + mTmpAppsList = apps; + pendingExecutor.execute(mBindAllApplicationsRunnable); + return; + } mAppsView.setApps(apps); } if (mLauncherCallbacks != null) { @@ -3710,6 +3723,14 @@ public class Launcher extends BaseActivity } /** + * Returns an Executor that will run after the launcher is first drawn (including after the + * initial fade in animation). Returns null if the first draw has already occurred. + */ + public @Nullable Executor getPendingExecutor() { + return mPendingExecutor != null && mPendingExecutor.canQueue() ? mPendingExecutor : null; + } + + /** * Copies LauncherModel's map of activities to shortcut ids to Launcher's. This is necessary * because LauncherModel's map is updated in the background, while Launcher runs on the UI. */ @@ -3901,6 +3922,12 @@ public class Launcher extends BaseActivity } if (mWidgetsView != null && allWidgets != null) { + Executor pendingExecutor = getPendingExecutor(); + if (pendingExecutor != null && mState != State.WIDGETS) { + mAllWidgets = allWidgets; + pendingExecutor.execute(mBindAllWidgetsRunnable); + return; + } mWidgetsView.setWidgets(allWidgets); mAllWidgets = null; } diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index cf20febd5..1ffe41bc6 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -16,6 +16,7 @@ package com.android.launcher3; +import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.Context; import android.content.Intent; @@ -28,13 +29,17 @@ import com.android.launcher3.compat.PackageInstallerCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dynamicui.ExtractionUtils; +import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.util.ConfigMonitor; import com.android.launcher3.util.Preconditions; +import com.android.launcher3.util.SettingsObserver; import com.android.launcher3.util.TestingUtils; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING; + public class LauncherAppState { public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD; @@ -47,7 +52,7 @@ public class LauncherAppState { private final IconCache mIconCache; private final WidgetPreviewLoader mWidgetCache; private final InvariantDeviceProfile mInvariantDeviceProfile; - + private final SettingsObserver mNotificationBadgingObserver; public static LauncherAppState getInstance(final Context context) { if (INSTANCE == null) { @@ -117,6 +122,23 @@ public class LauncherAppState { new ConfigMonitor(mContext).register(); ExtractionUtils.startColorExtractionServiceIfNecessary(mContext); + + if (!mContext.getResources().getBoolean(R.bool.notification_badging_enabled)) { + mNotificationBadgingObserver = null; + } else { + // Register an observer to rebind the notification listener when badging is re-enabled. + mNotificationBadgingObserver = new SettingsObserver.Secure( + mContext.getContentResolver()) { + @Override + public void onSettingChanged(boolean isNotificationBadgingEnabled) { + if (isNotificationBadgingEnabled) { + NotificationListener.requestRebind(new ComponentName( + mContext, NotificationListener.class)); + } + } + }; + mNotificationBadgingObserver.register(NOTIFICATION_BADGING); + } } /** @@ -127,6 +149,9 @@ public class LauncherAppState { final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext); launcherApps.removeOnAppsChangedCallback(mModel); PackageInstallerCompat.getInstance(mContext).onStop(); + if (mNotificationBadgingObserver != null) { + mNotificationBadgingObserver.unregister(); + } } LauncherModel setLauncher(Launcher launcher) { diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java index 6e8c59b66..5573c5c15 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHost.java +++ b/src/com/android/launcher3/LauncherAppWidgetHost.java @@ -16,12 +16,20 @@ package com.android.launcher3; +import android.app.Activity; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHostView; +import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; +import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.Intent; +import android.os.Handler; import android.util.SparseArray; import android.view.LayoutInflater; +import android.widget.Toast; + +import com.android.launcher3.config.FeatureFlags; import java.util.ArrayList; @@ -33,14 +41,16 @@ import java.util.ArrayList; */ public class LauncherAppWidgetHost extends AppWidgetHost { - private final ArrayList<Runnable> mProviderChangeListeners = new ArrayList<Runnable>(); + public static final int APPWIDGET_HOST_ID = 1024; + + private final ArrayList<ProviderChangedListener> mProviderChangeListeners = new ArrayList<>(); private final SparseArray<LauncherAppWidgetHostView> mViews = new SparseArray<>(); - private Launcher mLauncher; + private final Context mContext; - public LauncherAppWidgetHost(Launcher launcher, int hostId) { - super(launcher, hostId); - mLauncher = launcher; + public LauncherAppWidgetHost(Context context) { + super(context, APPWIDGET_HOST_ID); + mContext = context; } @Override @@ -53,6 +63,10 @@ public class LauncherAppWidgetHost extends AppWidgetHost { @Override public void startListening() { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return; + } + try { super.startListening(); } catch (Exception e) { @@ -66,24 +80,38 @@ public class LauncherAppWidgetHost extends AppWidgetHost { } } - public void addProviderChangeListener(Runnable callback) { + @Override + public void stopListening() { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return; + } + + super.stopListening(); + } + + @Override + public int allocateAppWidgetId() { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return AppWidgetManager.INVALID_APPWIDGET_ID; + } + + return super.allocateAppWidgetId(); + } + + public void addProviderChangeListener(ProviderChangedListener callback) { mProviderChangeListeners.add(callback); } - public void removeProviderChangeListener(Runnable callback) { + public void removeProviderChangeListener(ProviderChangedListener callback) { mProviderChangeListeners.remove(callback); } protected void onProvidersChanged() { if (!mProviderChangeListeners.isEmpty()) { - for (Runnable callback : new ArrayList<>(mProviderChangeListeners)) { - callback.run(); + for (ProviderChangedListener callback : new ArrayList<>(mProviderChangeListeners)) { + callback.notifyWidgetProvidersChanged(); } } - - if (Utilities.ATLEAST_MARSHMALLOW) { - mLauncher.notifyWidgetProvidersChanged(); - } } public AppWidgetHostView createView(Context context, int appWidgetId, @@ -109,7 +137,7 @@ public class LauncherAppWidgetHost extends AppWidgetHost { // will update. LauncherAppWidgetHostView view = mViews.get(appWidgetId); if (view == null) { - view = onCreateView(mLauncher, appWidgetId, appWidget); + view = onCreateView(mContext, appWidgetId, appWidget); } view.setAppWidget(appWidgetId, appWidget); view.switchToErrorView(); @@ -124,11 +152,11 @@ public class LauncherAppWidgetHost extends AppWidgetHost { @Override protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) { LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo.fromProviderInfo( - mLauncher, appWidget); + mContext, appWidget); super.onProviderChanged(appWidgetId, info); // The super method updates the dimensions of the providerInfo. Update the // launcher spans accordingly. - info.initSpans(mLauncher); + info.initSpans(mContext); } @Override @@ -142,4 +170,53 @@ public class LauncherAppWidgetHost extends AppWidgetHost { super.clearViews(); mViews.clear(); } + + public void startBindFlow(BaseActivity activity, + int appWidgetId, AppWidgetProviderInfo info, int requestCode) { + + if (FeatureFlags.GO_DISABLE_WIDGETS) { + sendActionCancelled(activity, requestCode); + return; + } + + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, info.getProfile()); + // TODO: we need to make sure that this accounts for the options bundle. + // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); + activity.startActivityForResult(intent, requestCode); + } + + + public void startConfigActivity(BaseActivity activity, int widgetId, int requestCode) { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + sendActionCancelled(activity, requestCode); + return; + } + + try { + startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, null); + } catch (ActivityNotFoundException | SecurityException e) { + Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); + sendActionCancelled(activity, requestCode); + } + } + + private void sendActionCancelled(final BaseActivity activity, final int requestCode) { + new Handler().post(new Runnable() { + @Override + public void run() { + activity.onActivityResult(requestCode, Activity.RESULT_CANCELED, null); + } + }); + } + + /** + * Listener for getting notifications on provider changes. + */ + public interface ProviderChangedListener { + + void notifyWidgetProvidersChanged(); + } } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 82bee0e4c..100774866 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -133,7 +133,7 @@ public class LauncherModel extends BroadcastReceiver } }; - public interface Callbacks { + public interface Callbacks extends LauncherAppWidgetHost.ProviderChangedListener { public boolean setLoadOnResume(); public int getCurrentWorkspaceScreen(); public void clearPendingBinds(); @@ -159,7 +159,6 @@ public class LauncherModel extends BroadcastReceiver HashSet<String> packageNames, HashSet<ComponentName> components, UserHandle user); public void bindAppInfosRemoved(ArrayList<AppInfo> appInfos); - public void notifyWidgetProvidersChanged(); public void bindAllWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets); public void onPageBoundSynchronously(int page); public void executeOnNextDraw(ViewOnDrawExecutor executor); @@ -690,4 +689,8 @@ public class LauncherModel extends BroadcastReceiver public static Looper getWorkerLooper() { return sWorkerThread.getLooper(); } + + public static void setWorkerPriority(final int priority) { + Process.setThreadPriority(sWorkerThread.getThreadId(), priority); + } } diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 4813571f5..dc83f36ad 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -1031,7 +1031,7 @@ public class LauncherProvider extends ContentProvider { } public AppWidgetHost newLauncherWidgetHost() { - return new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID); + return new LauncherAppWidgetHost(mContext); } @Override diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 185c8879d..87f3ddaf4 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -48,6 +48,7 @@ import android.view.animation.Interpolator; import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.pageindicators.PageIndicator; +import com.android.launcher3.touch.OverScroll; import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; @@ -68,10 +69,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc public static final int PAGE_SNAP_ANIMATION_DURATION = 750; protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950; - // Overscroll constants + // OverScroll constants private final static int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270; - private static final float OVERSCROLL_ACCELERATE_FACTOR = 2; - private static final float OVERSCROLL_DAMP_FACTOR = 0.07f; private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f; // The page is moved more than halfway, automatically move to the next page on touch up. @@ -188,7 +187,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc // Convenience/caching private static final Matrix sTmpInvMatrix = new Matrix(); private static final float[] sTmpPoint = new float[2]; - private static final int[] sTmpIntPoint = new int[2]; private static final Rect sTmpRect = new Rect(); protected final Rect mInsets = new Rect(); @@ -233,8 +231,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * density); setOnHierarchyChangeListener(this); setWillNotDraw(false); - - int edgeEffectColor = Themes.getAttrColor(getContext(), android.R.attr.colorEdgeEffect); } protected void setDefaultInterpolator(Interpolator interpolator) { @@ -1305,29 +1301,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } } - // This curve determines how the effect of scrolling over the limits of the page dimishes - // as the user pulls further and further from the bounds - private float overScrollInfluenceCurve(float f) { - f -= 1.0f; - return f * f * f + 1.0f; - } - - protected float acceleratedOverFactor(float amount) { - int screenSize = getViewportWidth(); - - // We want to reach the max over scroll effect when the user has - // over scrolled half the size of the screen - float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize); - - if (Float.compare(f, 0f) == 0) return 0; - - // Clamp this factor, f, to -1 < f < 1 - if (Math.abs(f) >= 1) { - f /= Math.abs(f); - } - return f; - } - // While layout transitions are occurring, a child's position may stray from its baseline // position. This method returns the magnitude of this stray at any given time. public int getLayoutTransitionOffsetForPage(int index) { @@ -1348,20 +1321,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } protected void dampedOverScroll(float amount) { - int screenSize = getViewportWidth(); - - float f = (amount / screenSize); - - if (Float.compare(f, 0f) == 0) return; - - f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f))); + if (Float.compare(amount, 0f) == 0) return; - // Clamp this factor, f, to -1 < f < 1 - if (Math.abs(f) >= 1) { - f /= Math.abs(f); - } - - int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize); + int overScrollAmount = OverScroll.dampedScroll(amount, getViewportWidth()); if (amount < 0) { mOverScrollX = overScrollAmount; super.scrollTo(mOverScrollX, getScrollY()); @@ -1376,14 +1338,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc dampedOverScroll(amount); } - protected float maxOverScroll() { - // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not - // exceed). Used to find out how much extra wallpaper we need for the over scroll effect - float f = 1.0f; - f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f))); - return OVERSCROLL_DAMP_FACTOR * f; - } - /** * return true if freescroll has been enabled, false otherwise */ diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java index fa7769e3f..90463725f 100644 --- a/src/com/android/launcher3/SettingsActivity.java +++ b/src/com/android/launcher3/SettingsActivity.java @@ -26,17 +26,15 @@ import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.database.ContentObserver; import android.os.Bundle; -import android.os.Handler; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.provider.Settings; -import android.provider.Settings.System; import com.android.launcher3.graphics.IconShapeOverride; import com.android.launcher3.notification.NotificationListener; +import com.android.launcher3.util.SettingsObserver; import com.android.launcher3.views.ButtonPreference; /** @@ -45,8 +43,8 @@ import com.android.launcher3.views.ButtonPreference; public class SettingsActivity extends Activity { private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging"; - // TODO: use Settings.Secure.NOTIFICATION_BADGING - private static final String NOTIFICATION_BADGING = "notification_badging"; + /** Hidden field Settings.Secure.NOTIFICATION_BADGING */ + public static final String NOTIFICATION_BADGING = "notification_badging"; /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */ private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners"; @@ -88,12 +86,9 @@ public class SettingsActivity extends Activity { // Register a content observer to listen for system setting changes while // this UI is active. - resolver.registerContentObserver( - Settings.System.getUriFor(System.ACCELEROMETER_ROTATION), - false, mRotationLockObserver); + mRotationLockObserver.register(Settings.System.ACCELEROMETER_ROTATION); // Initialize the UI once - mRotationLockObserver.onChange(true); rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity())); } @@ -107,13 +102,7 @@ public class SettingsActivity extends Activity { // Listen to system notification badge settings while this UI is active. mIconBadgingObserver = new IconBadgingObserver( iconBadgingPref, resolver, getFragmentManager()); - resolver.registerContentObserver( - Settings.Secure.getUriFor(NOTIFICATION_BADGING), - false, mIconBadgingObserver); - resolver.registerContentObserver( - Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS), - false, mIconBadgingObserver); - mIconBadgingObserver.onChange(true); + mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS); } Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE); @@ -129,11 +118,11 @@ public class SettingsActivity extends Activity { @Override public void onDestroy() { if (mRotationLockObserver != null) { - getActivity().getContentResolver().unregisterContentObserver(mRotationLockObserver); + mRotationLockObserver.unregister(); mRotationLockObserver = null; } if (mIconBadgingObserver != null) { - getActivity().getContentResolver().unregisterContentObserver(mIconBadgingObserver); + mIconBadgingObserver.unregister(); mIconBadgingObserver = null; } super.onDestroy(); @@ -144,22 +133,18 @@ public class SettingsActivity extends Activity { * Content observer which listens for system auto-rotate setting changes, and enables/disables * the launcher rotation setting accordingly. */ - private static class SystemDisplayRotationLockObserver extends ContentObserver { + private static class SystemDisplayRotationLockObserver extends SettingsObserver.System { private final Preference mRotationPref; - private final ContentResolver mResolver; public SystemDisplayRotationLockObserver( Preference rotationPref, ContentResolver resolver) { - super(new Handler()); + super(resolver); mRotationPref = rotationPref; - mResolver = resolver; } @Override - public void onChange(boolean selfChange) { - boolean enabled = Settings.System.getInt(mResolver, - Settings.System.ACCELEROMETER_ROTATION, 1) == 1; + public void onSettingChanged(boolean enabled) { mRotationPref.setEnabled(enabled); mRotationPref.setSummary(enabled ? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc); @@ -170,7 +155,7 @@ public class SettingsActivity extends Activity { * Content observer which listens for system badging setting changes, * and updates the launcher badging setting subtext accordingly. */ - private static class IconBadgingObserver extends ContentObserver + private static class IconBadgingObserver extends SettingsObserver.Secure implements Preference.OnPreferenceClickListener { private final ButtonPreference mBadgingPref; @@ -179,15 +164,14 @@ public class SettingsActivity extends Activity { public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver, FragmentManager fragmentManager) { - super(new Handler()); + super(resolver); mBadgingPref = badgingPref; mResolver = resolver; mFragmentManager = fragmentManager; } @Override - public void onChange(boolean selfChange) { - boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1; + public void onSettingChanged(boolean enabled) { int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off; boolean serviceEnabled = true; diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index fd708c0fd..a7e68ff14 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -101,7 +101,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup { mInvertIfRtl = invert; } - int getCellContentHeight() { + public int getCellContentHeight() { return Math.min(getMeasuredHeight(), mLauncher.getDeviceProfile().getCellHeight(mContainerType)); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index f781a3d1d..f8d64984e 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -52,8 +52,10 @@ import android.view.accessibility.AccessibilityManager; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.widget.Toast; + import com.android.launcher3.Launcher.CustomContentCallbacks; import com.android.launcher3.Launcher.LauncherOverlay; +import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.UninstallDropTarget.DropTargetSource; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.accessibility.OverviewAccessibilityDelegate; @@ -86,6 +88,7 @@ import com.android.launcher3.util.VerticalFlingDetector; import com.android.launcher3.util.WallpaperOffsetInterpolator; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; + import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -668,7 +671,8 @@ public class Workspace extends PagedView newScreen.setSoundEffectsEnabled(false); int paddingLeftRight = mLauncher.getDeviceProfile().cellLayoutPaddingLeftRightPx; - newScreen.setPadding(paddingLeftRight, 0, paddingLeftRight, 0); + int paddingBottom = mLauncher.getDeviceProfile().cellLayoutBottomPaddingPx; + newScreen.setPadding(paddingLeftRight, 0, paddingLeftRight, paddingBottom); mWorkspaceScreens.put(screenId, newScreen); mScreenOrder.add(insertIndex, screenId); @@ -4079,7 +4083,7 @@ public class Workspace extends PagedView * Used as a workaround to ensure that the AppWidgetService receives the * PACKAGE_ADDED broadcast before updating widgets. */ - private class DeferredWidgetRefresh implements Runnable { + private class DeferredWidgetRefresh implements Runnable, ProviderChangedListener { private final ArrayList<LauncherAppWidgetInfo> mInfos; private final LauncherAppWidgetHost mHost; private final Handler mHandler; @@ -4122,6 +4126,11 @@ public class Workspace extends PagedView } }); } + + @Override + public void notifyWidgetProvidersChanged() { + run(); + } } private class StateTransitionListener extends AnimatorListenerAdapter diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java index 816121995..b7c500fa6 100644 --- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java @@ -50,8 +50,7 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele if ((host.getParent() instanceof DeepShortcutView)) { info.addAction(mActions.get(ADD_TO_WORKSPACE)); } else if (host instanceof NotificationMainView) { - NotificationMainView notificationView = (NotificationMainView) host; - if (notificationView.canChildBeDismissed(notificationView)) { + if (((NotificationMainView) host).canChildBeDismissed()) { info.addAction(mActions.get(DISMISS_NOTIFICATION)); } } @@ -88,8 +87,7 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele if (!(host instanceof NotificationMainView)) { return false; } - NotificationMainView notificationView = (NotificationMainView) host; - notificationView.onChildDismissed(notificationView); + ((NotificationMainView) host).onChildDismissed(); announceConfirmation(R.string.notification_dismissed); return true; } diff --git a/src/com/android/launcher3/allapps/AllAppsCaretController.java b/src/com/android/launcher3/allapps/AllAppsCaretController.java index 622322bfc..583b49f7b 100644 --- a/src/com/android/launcher3/allapps/AllAppsCaretController.java +++ b/src/com/android/launcher3/allapps/AllAppsCaretController.java @@ -22,13 +22,14 @@ import android.view.animation.Interpolator; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.pageindicators.CaretDrawable; +import com.android.launcher3.touch.SwipeDetector; public class AllAppsCaretController { // Determines when the caret should flip. Should be accessed via getThreshold() private static final float CARET_THRESHOLD = 0.015f; private static final float CARET_THRESHOLD_LAND = 0.5f; // The velocity at which the caret will peak (i.e. exhibit a 90 degree bend) - private static final float PEAK_VELOCITY = VerticalPullDetector.RELEASE_VELOCITY_PX_MS * .7f; + private static final float PEAK_VELOCITY = SwipeDetector.RELEASE_VELOCITY_PX_MS * .7f; private Launcher mLauncher; diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 657af15cb..494cd5ac5 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -36,6 +36,8 @@ import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.DrawableFactory; import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; +import com.android.launcher3.touch.OverScroll; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; @@ -60,7 +62,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine private SpringAnimationHandler mSpringAnimationHandler; private OverScrollHelper mOverScrollHelper; - private VerticalPullDetector mPullDetector; + private SwipeDetector mPullDetector; private float mContentTranslationY = 0; public static final Property<AllAppsRecyclerView, Float> CONTENT_TRANS_Y = @@ -97,9 +99,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine R.dimen.all_apps_empty_search_bg_top_offset); mOverScrollHelper = new OverScrollHelper(); - mPullDetector = new VerticalPullDetector(getContext()); - mPullDetector.setListener(mOverScrollHelper); - mPullDetector.setDetectableScrollConditions(VerticalPullDetector.DIRECTION_BOTH, true); + mPullDetector = new SwipeDetector(getContext(), mOverScrollHelper, SwipeDetector.VERTICAL); + mPullDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, true); } public void setSpringAnimationHandler(SpringAnimationHandler springAnimationHandler) { @@ -198,8 +199,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine @Override public void onDraw(Canvas c) { - c.translate(0, mContentTranslationY); - // Draw the background if (mEmptySearchBackground != null && mEmptySearchBackground.getAlpha() > 0) { mEmptySearchBackground.draw(c); @@ -208,6 +207,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine super.onDraw(c); } + @Override + protected void dispatchDraw(Canvas canvas) { + canvas.translate(0, mContentTranslationY); + super.dispatchDraw(canvas); + canvas.translate(0, -mContentTranslationY); + } + public float getContentTranslationY() { return mContentTranslationY; } @@ -333,6 +339,22 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine mFastScrollHelper.onSetAdapter((AllAppsGridAdapter) adapter); } + @Override + protected float getBottomFadingEdgeStrength() { + // No bottom fading edge. + return 0; + } + + @Override + protected boolean isPaddingOffsetRequired() { + return true; + } + + @Override + protected int getTopPaddingOffset() { + return -getPaddingTop(); + } + /** * Updates the bounds for the scrollbar. */ @@ -502,7 +524,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine } } - private class OverScrollHelper implements VerticalPullDetector.Listener { + private class OverScrollHelper implements SwipeDetector.Listener { private static final float MAX_RELEASE_VELOCITY = 5000; // px / s private static final float MAX_OVERSCROLL_PERCENTAGE = 0.07f; @@ -589,37 +611,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine } private float getDampedOverScroll(float y) { - return dampedOverScroll(y, getHeight()) * MAX_OVERSCROLL_PERCENTAGE; - } - - /** - * This curve determines how the effect of scrolling over the limits of the page diminishes - * as the user pulls further and further from the bounds - * - * @param f The percentage of how much the user has overscrolled. - * @return A transformed percentage based on the influence curve. - */ - private float overScrollInfluenceCurve(float f) { - f -= 1.0f; - return f * f * f + 1.0f; - } - - /** - * @param amount The original amount overscrolled. - * @param max The maximum amount that the View can overscroll. - * @return The dampened overscroll amount. - */ - private float dampedOverScroll(float amount, float max) { - float f = amount / max; - if (Float.compare(f, 0) == 0) return 0; - f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f))); - - // Clamp this factor, f, to -1 < f < 1 - if (Math.abs(f) >= 1) { - f /= Math.abs(f); - } - - return Math.round(f * max); + return OverScroll.dampedScroll(y, getHeight()); } } } diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index b85321e63..edfe0c15e 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -25,6 +25,7 @@ import com.android.launcher3.Workspace; import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.GradientView; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.SystemUiController; @@ -41,7 +42,7 @@ import com.android.launcher3.util.TouchController; * If release velocity < THRES1, snap according to either top or bottom depending on whether it's * closer to top or closer to the page indicator. */ -public class AllAppsTransitionController implements TouchController, VerticalPullDetector.Listener, +public class AllAppsTransitionController implements TouchController, SwipeDetector.Listener, SearchUiManager.OnScrollRangeChangeListener { private static final String TAG = "AllAppsTrans"; @@ -51,8 +52,8 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(1.5f); private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f); private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator(); - private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator - = new VerticalPullDetector.ScrollInterpolator(); + private final SwipeDetector.ScrollInterpolator mScrollInterpolator + = new SwipeDetector.ScrollInterpolator(); private static final float PARALLAX_COEFFICIENT = .125f; private static final int SINGLE_FRAME_MS = 16; @@ -68,7 +69,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private float mStatusBarHeight; private final Launcher mLauncher; - private final VerticalPullDetector mDetector; + private final SwipeDetector mDetector; private final ArgbEvaluator mEvaluator; private final boolean mIsDarkTheme; @@ -104,8 +105,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul public AllAppsTransitionController(Launcher l) { mLauncher = l; - mDetector = new VerticalPullDetector(l); - mDetector.setListener(this); + mDetector = new SwipeDetector(l, this, SwipeDetector.VERTICAL); mShiftRange = DEFAULT_SHIFT_RANGE; mProgress = 1f; @@ -134,17 +134,17 @@ public class AllAppsTransitionController implements TouchController, VerticalPul if (mDetector.isIdleState()) { if (mLauncher.isAllAppsVisible()) { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_DOWN; + directionsToDetectScroll |= SwipeDetector.DIRECTION_NEGATIVE; } else { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_UP; + directionsToDetectScroll |= SwipeDetector.DIRECTION_POSITIVE; } } else { if (isInDisallowRecatchBottomZone()) { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_UP; + directionsToDetectScroll |= SwipeDetector.DIRECTION_POSITIVE; } else if (isInDisallowRecatchTopZone()) { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_DOWN; + directionsToDetectScroll |= SwipeDetector.DIRECTION_NEGATIVE; } else { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_BOTH; + directionsToDetectScroll |= SwipeDetector.DIRECTION_BOTH; ignoreSlopWhenSettling = true; } } @@ -360,7 +360,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul } private void calculateDuration(float velocity, float disp) { - mAnimationDuration = mDetector.calculateDuration(velocity, disp / mShiftRange); + mAnimationDuration = SwipeDetector.calculateDuration(velocity, disp / mShiftRange); } public boolean animateToAllApps(AnimatorSet animationOut, long duration) { diff --git a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java index 21eb3fba0..26f6ec357 100644 --- a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java +++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java @@ -71,10 +71,6 @@ public class DefaultAppSearchAlgorithm implements SearchAlgorithm { return result; } - public static boolean matches(AppInfo info, String query) { - return matches(info, query, StringMatcher.getInstance()); - } - public static boolean matches(AppInfo info, String query, StringMatcher matcher) { int queryLength = query.length(); diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java index 3efbbfba5..4e00eae9d 100644 --- a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java +++ b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java @@ -16,15 +16,12 @@ package com.android.launcher3.compat; -import android.app.Activity; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.os.Bundle; import android.os.UserHandle; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.android.launcher3.LauncherAppWidgetProviderInfo; @@ -76,9 +73,6 @@ public abstract class AppWidgetManagerCompat { public abstract boolean bindAppWidgetIdIfAllowed( int appWidgetId, AppWidgetProviderInfo info, Bundle options); - public abstract void startConfigActivity(AppWidgetProviderInfo info, int widgetId, - Activity activity, AppWidgetHost host, int requestCode); - public abstract LauncherAppWidgetProviderInfo findProvider( ComponentName provider, UserHandle user); diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java index f239f5c31..cb3bd6c7d 100644 --- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java +++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java @@ -16,24 +16,21 @@ package com.android.launcher3.compat; -import android.app.Activity; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetProviderInfo; -import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.support.annotation.Nullable; -import android.widget.Toast; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.PackageUserKey; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -49,6 +46,9 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat { @Override public List<AppWidgetProviderInfo> getAllProviders(@Nullable PackageUserKey packageUser) { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return Collections.emptyList(); + } if (packageUser == null) { ArrayList<AppWidgetProviderInfo> providers = new ArrayList<AppWidgetProviderInfo>(); for (UserHandle user : mUserManager.getUserProfiles()) { @@ -71,24 +71,20 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat { @Override public boolean bindAppWidgetIdIfAllowed(int appWidgetId, AppWidgetProviderInfo info, Bundle options) { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return false; + } return mAppWidgetManager.bindAppWidgetIdIfAllowed( appWidgetId, info.getProfile(), info.provider, options); } @Override - public void startConfigActivity(AppWidgetProviderInfo info, int widgetId, Activity activity, - AppWidgetHost host, int requestCode) { - try { - host.startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, null); - } catch (ActivityNotFoundException | SecurityException e) { - Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); - } - } - - @Override public LauncherAppWidgetProviderInfo findProvider(ComponentName provider, UserHandle user) { - for (AppWidgetProviderInfo info : mAppWidgetManager - .getInstalledProvidersForProfile(user)) { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return null; + } + for (AppWidgetProviderInfo info : + getAllProviders(new PackageUserKey(provider.getPackageName(), user))) { if (info.provider.equals(provider)) { return LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info); } @@ -99,6 +95,9 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat { @Override public HashMap<ComponentKey, AppWidgetProviderInfo> getAllProvidersMap() { HashMap<ComponentKey, AppWidgetProviderInfo> result = new HashMap<>(); + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return result; + } for (UserHandle user : mUserManager.getUserProfiles()) { for (AppWidgetProviderInfo info : mAppWidgetManager.getInstalledProvidersForProfile(user)) { diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java index 1c48a13bd..44158edbf 100644 --- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java +++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java @@ -20,8 +20,10 @@ import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.support.annotation.Nullable; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.PackageUserKey; +import java.util.Collections; import java.util.List; class AppWidgetManagerCompatVO extends AppWidgetManagerCompatVL { @@ -32,6 +34,9 @@ class AppWidgetManagerCompatVO extends AppWidgetManagerCompatVL { @Override public List<AppWidgetProviderInfo> getAllProviders(@Nullable PackageUserKey packageUser) { + if (FeatureFlags.GO_DISABLE_WIDGETS) { + return Collections.emptyList(); + } if (packageUser == null) { return super.getAllProviders(null); } diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java new file mode 100644 index 000000000..7964dd15d --- /dev/null +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -0,0 +1,73 @@ +/* + * 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.config; + +/** + * Defines a set of flags used to control various launcher behaviors. + * + * All the flags should be defined here with appropriate default values. To override a value, + * redefine it in {@link FeatureFlags}. + * + * This class is kept package-private to prevent direct access. + */ +abstract class BaseFlags { + + BaseFlags() {} + + public static final boolean IS_DOGFOOD_BUILD = false; + + // Custom flags go below this + public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false; + public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false; + 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 = true; + // When enabled allows to use any point on the fast scrollbar to start dragging. + public static final boolean LAUNCHER3_DIRECT_SCROLL = true; + // When enabled while all-apps open, the soft input will be set to adjust resize . + public static final boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = false; + // When enabled the promise icon is visible in all apps while installation an app. + public static final boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false; + // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps + public static final boolean LAUNCHER3_GRADIENT_ALL_APPS = true; + // When enabled allows use of physics based motions in the Launcher. + public static final boolean LAUNCHER3_PHYSICS = true; + // When enabled allows use of spring motions on the icons. + public static final boolean LAUNCHER3_SPRING_ICONS = true; + + // Feature flag to enable moving the QSB on the 0th screen of the workspace. + public static final boolean QSB_ON_FIRST_SCREEN = true; + // When enabled the all-apps icon is not added to the hotseat. + public static final boolean NO_ALL_APPS_ICON = true; + // When enabled fling down gesture on the first workspace triggers search. + public static final boolean PULLDOWN_SEARCH = false; + // When enabled the status bar may show dark icons based on the top of the wallpaper. + public static final boolean LIGHT_STATUS_BAR = false; + // When enabled 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 {@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; + + // Features to control Launcher3Go behavior + public static final boolean GO_DISABLE_WIDGETS = false; +} diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 01893bdaf..c843e7266 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -16,14 +16,8 @@ package com.android.launcher3.dragndrop; -import static com.android.launcher3.logging.LoggerUtils.newCommandAction; -import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; -import static com.android.launcher3.logging.LoggerUtils.newItemTarget; -import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent; - import android.annotation.TargetApi; import android.app.ActivityOptions; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.content.ClipData; import android.content.ClipDescription; @@ -45,8 +39,8 @@ import android.view.View.OnTouchListener; import com.android.launcher3.BaseActivity; import com.android.launcher3.InstallShortcutReceiver; import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -61,6 +55,11 @@ import com.android.launcher3.widget.PendingAddWidgetInfo; import com.android.launcher3.widget.WidgetHostViewLoader; import com.android.launcher3.widget.WidgetImageView; +import static com.android.launcher3.logging.LoggerUtils.newCommandAction; +import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; +import static com.android.launcher3.logging.LoggerUtils.newItemTarget; +import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent; + @TargetApi(Build.VERSION_CODES.O) public class AddItemActivity extends BaseActivity implements OnLongClickListener, OnTouchListener { @@ -78,7 +77,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener private LivePreviewWidgetCell mWidgetCell; // Widget request specific options. - private AppWidgetHost mAppWidgetHost; + private LauncherAppWidgetHost mAppWidgetHost; private AppWidgetManagerCompat mAppWidgetManager; private PendingAddWidgetInfo mPendingWidgetInfo; private int mPendingBindWidgetId; @@ -212,7 +211,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener mWidgetCell.setPreview(PinItemDragListener.getPreview(mRequest)); mAppWidgetManager = AppWidgetManagerCompat.getInstance(this); - mAppWidgetHost = new AppWidgetHost(this, Launcher.APPWIDGET_HOST_ID); + mAppWidgetHost = new LauncherAppWidgetHost(this); mPendingWidgetInfo = new PendingAddWidgetInfo(widgetInfo); mPendingWidgetInfo.spanX = Math.min(mIdp.numColumns, widgetInfo.spanX); @@ -256,13 +255,8 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener } // request bind widget - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingBindWidgetId); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, - mPendingWidgetInfo.componentName); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, - mRequest.getAppWidgetProviderInfo(this).getProfile()); - startActivityForResult(intent, REQUEST_BIND_APPWIDGET); + mAppWidgetHost.startBindFlow(this, mPendingBindWidgetId, + mRequest.getAppWidgetProviderInfo(this), REQUEST_BIND_APPWIDGET); } private void acceptWidget(int widgetId) { @@ -280,7 +274,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_BIND_APPWIDGET) { int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingBindWidgetId) diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index 09cfc1eac..e81e2a386 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -16,23 +16,18 @@ package com.android.launcher3.dragndrop; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; - import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.FloatArrayEvaluator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.pm.LauncherActivityInfo; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.ColorFilter; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; -import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; @@ -44,13 +39,11 @@ import android.graphics.drawable.InsetDrawable; import android.os.Build; import android.os.Handler; import android.os.Looper; -import android.support.animation.DynamicAnimation; +import android.support.animation.FloatPropertyCompat; import android.support.animation.SpringAnimation; import android.support.animation.SpringForce; import android.view.View; import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.ImageView; import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.ItemInfo; @@ -76,12 +69,16 @@ import com.android.launcher3.widget.PendingAddShortcutInfo; import java.util.Arrays; import java.util.List; -public class DragView extends FrameLayout { +public class DragView extends View { + private static final ColorMatrix sTempMatrix1 = new ColorMatrix(); + private static final ColorMatrix sTempMatrix2 = new ColorMatrix(); + public static final int COLOR_CHANGE_DURATION = 120; public static final int VIEW_ZOOM_DURATION = 150; @Thunk static float sDragAlpha = 1f; + private boolean mDrawBitmap = true; private Bitmap mBitmap; private Bitmap mCrossFadeBitmap; @Thunk Paint mPaint; @@ -114,16 +111,11 @@ public class DragView extends FrameLayout { private int mAnimatedShiftY; // Below variable only needed IF FeatureFlags.LAUNCHER3_SPRING_ICONS is {@code true} - private SpringAnimation mSpringX, mSpringY; - private ImageView mFgImageView, mBgImageView; + private Drawable mBgSpringDrawable, mFgSpringDrawable; + private SpringFloatValue mTranslateX, mTranslateY; private Path mScaledMaskPath; private Drawable mBadge; - - // Following three values are fine tuned with motion ux designer - private final static int STIFFNESS = 4000; - private final static float DAMPENING_RATIO = 1f; - private final static int PARALLAX_MAX_IN_DP = 8; - private final int mDelta; + private ColorMatrixColorFilter mBaseFilter; /** * Construct the drag view. @@ -193,12 +185,11 @@ public class DragView extends FrameLayout { mBlurSizeOutline = getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline); setElevation(getResources().getDimension(R.dimen.drag_elevation)); - setWillNotDraw(false); - mDelta = (int)(getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP); } /** - * Initialize {@code #mIconDrawable} only if the icon type is app icon (not shortcut or folder). + * Initialize {@code #mIconDrawable} if the item can be represented using + * an {@link AdaptiveIconDrawable} or {@link FolderAdaptiveIcon}. */ @TargetApi(Build.VERSION_CODES.O) public void setItemInfo(final ItemInfo info) { @@ -206,7 +197,8 @@ public class DragView extends FrameLayout { return; } if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && - info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT && + info.itemType != LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { return; } // Load the adaptive icon on a background thread and add the view in ui thread. @@ -216,51 +208,106 @@ public class DragView extends FrameLayout { public void run() { LauncherAppState appState = LauncherAppState.getInstance(mLauncher); Object[] outObj = new Object[1]; - Drawable dr = getFullDrawable(info, appState, outObj); + final Drawable dr = getFullDrawable(info, appState, outObj); if (dr instanceof AdaptiveIconDrawable) { int w = mBitmap.getWidth(); int h = mBitmap.getHeight(); + int blurMargin = (int) mLauncher.getResources() + .getDimension(R.dimen.blur_size_medium_outline) / 2; + + Rect bounds = new Rect(0, 0, w, h); + bounds.inset(blurMargin, blurMargin); + // Badge is applied after icon normalization so the bounds for badge should not + // be scaled down due to icon normalization. + Rect badgeBounds = new Rect(bounds); + mBadge = getBadge(info, appState, outObj[0]); + mBadge.setBounds(badgeBounds); + + Utilities.scaleRectAboutCenter(bounds, + IconNormalizer.getInstance(mLauncher).getScale(dr, null, null, null)); AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr; - float blurSizeOutline = mLauncher.getResources() - .getDimension(R.dimen.blur_size_medium_outline); - float normalizationScale = IconNormalizer.getInstance(mLauncher) - .getScale(adaptiveIcon, null, null, null) * ((w - blurSizeOutline) / w); - adaptiveIcon.setBounds(0, 0, w, h); - - final Path mask = getMaskPath(adaptiveIcon, normalizationScale); - mFgImageView = setupImageView(adaptiveIcon.getForeground(), normalizationScale); - mBgImageView = setupImageView(adaptiveIcon.getBackground(), normalizationScale); - mSpringX = setupSpringAnimation(-w/4, w/4, DynamicAnimation.TRANSLATION_X); - mSpringY = setupSpringAnimation(-h/4, h/4, DynamicAnimation.TRANSLATION_Y); - mBadge = getBadge(info, appState, outObj[0]); - int blurMargin = (int) blurSizeOutline / 2; - mBadge.setBounds(blurMargin, blurMargin, w - blurMargin, h - blurMargin); + // Shrink very tiny bit so that the clip path is smaller than the original bitmap + // that has anti aliased edges and shadows. + Rect shrunkBounds = new Rect(bounds); + Utilities.scaleRectAboutCenter(shrunkBounds, 0.98f); + adaptiveIcon.setBounds(shrunkBounds); + final Path mask = adaptiveIcon.getIconMask(); + + mTranslateX = new SpringFloatValue(DragView.this, + w * AdaptiveIconDrawable.getExtraInsetFraction()); + mTranslateY = new SpringFloatValue(DragView.this, + h * AdaptiveIconDrawable.getExtraInsetFraction()); + + bounds.inset( + (int) (-bounds.width() * AdaptiveIconDrawable.getExtraInsetFraction()), + (int) (-bounds.height() * AdaptiveIconDrawable.getExtraInsetFraction()) + ); + mBgSpringDrawable = adaptiveIcon.getBackground(); + if (mBgSpringDrawable == null) { + mBgSpringDrawable = new ColorDrawable(Color.TRANSPARENT); + } + mBgSpringDrawable.setBounds(bounds); + mFgSpringDrawable = adaptiveIcon.getForeground(); + if (mFgSpringDrawable == null) { + mFgSpringDrawable = new ColorDrawable(Color.TRANSPARENT); + } + mFgSpringDrawable.setBounds(bounds); new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { // Assign the variable on the UI thread to avoid race conditions. mScaledMaskPath = mask; - addView(mBgImageView); - addView(mFgImageView); - setWillNotDraw(true); + + // Do not draw the background in case of folder as its translucent + mDrawBitmap = !(dr instanceof FolderAdaptiveIcon); if (info.isDisabled()) { FastBitmapDrawable d = new FastBitmapDrawable(null); d.setIsDisabled(true); - ColorFilter cf = d.getColorFilter(); - mBgImageView.setColorFilter(cf); - mFgImageView.setColorFilter(cf); - mBadge.setColorFilter(cf); + mBaseFilter = (ColorMatrixColorFilter) d.getColorFilter(); } + updateColorFilter(); } }); } }}); } + @TargetApi(Build.VERSION_CODES.O) + private void updateColorFilter() { + if (mCurrentFilter == null) { + mPaint.setColorFilter(null); + + if (mScaledMaskPath != null) { + mBgSpringDrawable.setColorFilter(mBaseFilter); + mBgSpringDrawable.setColorFilter(mBaseFilter); + mBadge.setColorFilter(mBaseFilter); + } + } else { + ColorMatrixColorFilter currentFilter = new ColorMatrixColorFilter(mCurrentFilter); + mPaint.setColorFilter(currentFilter); + + if (mScaledMaskPath != null) { + if (mBaseFilter != null) { + mBaseFilter.getColorMatrix(sTempMatrix1); + sTempMatrix2.set(mCurrentFilter); + sTempMatrix1.postConcat(sTempMatrix2); + + currentFilter = new ColorMatrixColorFilter(sTempMatrix1); + } + + mBgSpringDrawable.setColorFilter(currentFilter); + mFgSpringDrawable.setColorFilter(currentFilter); + mBadge.setColorFilter(currentFilter); + } + } + + invalidate(); + } + /** * Returns the full drawable for {@param info}. * @param outObj this is set to the internal data associated with {@param info}, @@ -291,6 +338,14 @@ public class DragView extends FrameLayout { return sm.getShortcutIconDrawable(si.get(0), appState.getInvariantDeviceProfile().fillResIconDpi); } + } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { + FolderAdaptiveIcon icon = FolderAdaptiveIcon.createFolderAdaptiveIcon( + mLauncher, info.id, new Point(mBitmap.getWidth(), mBitmap.getHeight())); + if (icon == null) { + return null; + } + outObj[0] = icon; + return icon; } else { return null; } @@ -318,84 +373,17 @@ public class DragView extends FrameLayout { float insetFraction = (iconSize - badgeSize) / iconSize; return new InsetDrawable(new FastBitmapDrawable(badge), insetFraction, insetFraction, 0, 0); + } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { + return ((FolderAdaptiveIcon) obj).getBadge(); } else { return mLauncher.getPackageManager() .getUserBadgedIcon(new FixedSizeEmptyDrawable(iconSize), info.user); } } - private ImageView setupImageView(Drawable drawable, float normalizationScale) { - FrameLayout.LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT); - ImageView imageViewOut = new ImageView(getContext()); - imageViewOut.setLayoutParams(params); - imageViewOut.setScaleType(ImageView.ScaleType.FIT_XY); - imageViewOut.setScaleX(normalizationScale); - imageViewOut.setScaleY(normalizationScale); - imageViewOut.setImageDrawable(drawable); - return imageViewOut; - } - - private SpringAnimation setupSpringAnimation(int minValue, int maxValue, - DynamicAnimation.ViewProperty property) { - SpringAnimation s = new SpringAnimation(mFgImageView, property, 0); - s.setMinValue(minValue).setMaxValue(maxValue); - s.setSpring(new SpringForce(0) - .setDampingRatio(DAMPENING_RATIO) - .setStiffness(STIFFNESS)); - return s; - } - - @TargetApi(Build.VERSION_CODES.O) - private Path getMaskPath(AdaptiveIconDrawable dr, float normalizationScale) { - Matrix m = new Matrix(); - // Shrink very tiny bit so that the clip path is smaller than the original bitmap - // that has anti aliased edges and shadows. - float s = normalizationScale * .97f; - m.setScale(s, s, dr.getBounds().centerX(), dr.getBounds().centerY()); - Path p = new Path(); - dr.getIconMask().transform(m, p); - return p; - } - - private void applySpring(int x, int y) { - if (mSpringX == null || mSpringY == null) { - return; - } - mSpringX.animateToFinalPosition(Utilities.boundToRange(x, -mDelta, mDelta)); - mSpringY.animateToFinalPosition(Utilities.boundToRange(y, -mDelta, mDelta)); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - int w = right - left; - int h = bottom - top; - for (int i = 0; i < getChildCount(); i++) { - getChildAt(i).layout(-w / 4, -h / 4, w + w / 4, h + h / 4); - } - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int w = mBitmap.getWidth(); - int h = mBitmap.getHeight(); - setMeasuredDimension(w, h); - for (int i = 0; i < getChildCount(); i++) { - getChildAt(i).measure(w, h); - } - } - - @Override - protected void dispatchDraw(Canvas canvas) { - if (mScaledMaskPath != null) { - int cnt = canvas.save(); - canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); - canvas.clipPath(mScaledMaskPath); - super.dispatchDraw(canvas); - canvas.restoreToCount(cnt); - mBadge.draw(canvas); - } else { - super.dispatchDraw(canvas); - } + setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight()); } /** Sets the scale of the view over the normal workspace icon size. */ @@ -439,43 +427,37 @@ public class DragView extends FrameLayout { return mDragRegion; } - // Draws drag shadow for system DND. - @SuppressLint("WrongCall") - public void drawDragShadow(Canvas canvas) { - final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); - canvas.scale(getScaleX(), getScaleY()); - onDraw(canvas); - canvas.restoreToCount(saveCount); - } - - // Provides drag shadow metrics for system DND. - public void provideDragShadowMetrics(Point size, Point touch) { - size.set((int)(mBitmap.getWidth() * getScaleX()), (int)(mBitmap.getHeight() * getScaleY())); - - final float xGrowth = mBitmap.getWidth() * (getScaleX() - 1); - final float yGrowth = mBitmap.getHeight() * (getScaleY() - 1); - touch.set( - mRegistrationX + (int)Math.round(xGrowth / 2), - mRegistrationY + (int)Math.round(yGrowth / 2)); - } - @Override protected void onDraw(Canvas canvas) { mHasDrawn = true; - boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null; - if (crossFade) { - int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255; - mPaint.setAlpha(alpha); + + if (mDrawBitmap) { + // Always draw the bitmap to mask anti aliasing due to clipPath + boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null; + if (crossFade) { + int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255; + mPaint.setAlpha(alpha); + } + canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); + if (crossFade) { + mPaint.setAlpha((int) (255 * mCrossFadeProgress)); + final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); + float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth(); + float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight(); + canvas.scale(sX, sY); + canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint); + canvas.restoreToCount(saveCount); + } } - canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); - if (crossFade) { - mPaint.setAlpha((int) (255 * mCrossFadeProgress)); - final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG); - float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth(); - float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight(); - canvas.scale(sX, sY); - canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint); - canvas.restoreToCount(saveCount); + + if (mScaledMaskPath != null) { + int cnt = canvas.save(); + canvas.clipPath(mScaledMaskPath); + mBgSpringDrawable.draw(canvas); + canvas.translate(mTranslateX.mValue, mTranslateY.mValue); + mFgSpringDrawable.draw(canvas); + canvas.restoreToCount(cnt); + mBadge.draw(canvas); } } @@ -512,8 +494,7 @@ public class DragView extends FrameLayout { animateFilterTo(m1.getArray()); } else { if (mCurrentFilter == null) { - mPaint.setColorFilter(null); - invalidate(); + updateColorFilter(); } else { animateFilterTo(new ColorMatrix().getArray()); } @@ -534,8 +515,7 @@ public class DragView extends FrameLayout { @Override public void onAnimationUpdate(ValueAnimator animation) { - mPaint.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter)); - invalidate(); + updateColorFilter(); } }); mFilterAnimator.start(); @@ -590,8 +570,10 @@ public class DragView extends FrameLayout { * @param touchY the y coordinate the user touched in DragLayer coordinates */ public void move(int touchX, int touchY) { - if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0) { - applySpring(mLastTouchX - touchX, mLastTouchY - touchY); + if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0 + && mScaledMaskPath != null) { + mTranslateX.animateToPos(mLastTouchX - touchX); + mTranslateY.animateToPos(mLastTouchY - touchY); } mLastTouchX = touchX; mLastTouchY = touchY; @@ -642,6 +624,48 @@ public class DragView extends FrameLayout { return mInitialScale; } + private static class SpringFloatValue { + + private static final FloatPropertyCompat<SpringFloatValue> VALUE = + new FloatPropertyCompat<SpringFloatValue>("value") { + @Override + public float getValue(SpringFloatValue object) { + return object.mValue; + } + + @Override + public void setValue(SpringFloatValue object, float value) { + object.mValue = value; + object.mView.invalidate(); + } + }; + + // Following three values are fine tuned with motion ux designer + private final static int STIFFNESS = 4000; + private final static float DAMPENING_RATIO = 1f; + private final static int PARALLAX_MAX_IN_DP = 8; + + private final View mView; + private final SpringAnimation mSpring; + private final float mDelta; + + private float mValue; + + public SpringFloatValue(View view, float range) { + mView = view; + mSpring = new SpringAnimation(this, VALUE, 0) + .setMinValue(-range).setMaxValue(range) + .setSpring(new SpringForce(0) + .setDampingRatio(DAMPENING_RATIO) + .setStiffness(STIFFNESS)); + mDelta = view.getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP; + } + + public void animateToPos(float value) { + mSpring.animateToFinalPosition(Utilities.boundToRange(value, -mDelta, mDelta)); + } + } + private static class FixedSizeEmptyDrawable extends ColorDrawable { private final int mSize; diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java new file mode 100644 index 000000000..c90546088 --- /dev/null +++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java @@ -0,0 +1,175 @@ +/* + * 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.dragndrop; + +import android.annotation.TargetApi; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.Point; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.Log; + +import com.android.launcher3.Launcher; +import com.android.launcher3.MainThreadExecutor; +import com.android.launcher3.R; +import com.android.launcher3.folder.FolderIcon; +import com.android.launcher3.folder.PreviewBackground; +import com.android.launcher3.util.Preconditions; + +import java.util.concurrent.Callable; + +/** + * {@link AdaptiveIconDrawable} representation of a {@link FolderIcon} + */ +@TargetApi(Build.VERSION_CODES.O) +public class FolderAdaptiveIcon extends AdaptiveIconDrawable { + private static final String TAG = "FolderAdaptiveIcon"; + + private final Drawable mBadge; + private final Path mMask; + + private FolderAdaptiveIcon(Drawable bg, Drawable fg, Drawable badge, Path mask) { + super(bg, fg); + mBadge = badge; + mMask = mask; + } + + @Override + public Path getIconMask() { + return mMask; + } + + public Drawable getBadge() { + return mBadge; + } + + public static FolderAdaptiveIcon createFolderAdaptiveIcon( + final Launcher launcher, final long folderId, Point dragViewSize) { + Preconditions.assertNonUiThread(); + int margin = launcher.getResources() + .getDimensionPixelSize(R.dimen.blur_size_medium_outline); + + // Allocate various bitmaps on the background thread, because why not! + final Bitmap badge = Bitmap.createBitmap( + dragViewSize.x - margin, dragViewSize.y - margin, Bitmap.Config.ARGB_8888); + + // The bitmap for the preview is generated larger than needed to allow for the spring effect + float sizeScaleFactor = 1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction(); + final Bitmap preview = Bitmap.createBitmap( + (int) (dragViewSize.x * sizeScaleFactor), (int) (dragViewSize.y * sizeScaleFactor), + Bitmap.Config.ARGB_8888); + + // Create the actual drawable on the UI thread to avoid race conditions with + // FolderIcon draw pass + try { + return new MainThreadExecutor().submit(new Callable<FolderAdaptiveIcon>() { + @Override + public FolderAdaptiveIcon call() throws Exception { + FolderIcon icon = launcher.findFolderIcon(folderId); + return icon == null ? null : createDrawableOnUiThread(icon, badge, preview); + } + }).get(); + } catch (Exception e) { + Log.e(TAG, "Unable to create folder icon", e); + return null; + } + } + + /** + * Initializes various bitmaps on the UI thread and returns the final drawable. + */ + private static FolderAdaptiveIcon createDrawableOnUiThread(FolderIcon icon, + Bitmap badgeBitmap, Bitmap previewBitmap) { + Preconditions.assertUIThread(); + float margin = icon.getResources().getDimension(R.dimen.blur_size_medium_outline) / 2; + + Canvas c = new Canvas(); + PreviewBackground bg = icon.getFolderBackground(); + + // Initialize badge + c.setBitmap(badgeBitmap); + bg.drawShadow(c); + bg.drawBackgroundStroke(c); + icon.drawBadge(c); + + // Initialize preview + float shiftFactor = AdaptiveIconDrawable.getExtraInsetFraction() / + (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction()); + float previewShiftX = shiftFactor * previewBitmap.getWidth(); + float previewShiftY = shiftFactor * previewBitmap.getHeight(); + + c.setBitmap(previewBitmap); + c.translate(previewShiftX, previewShiftY); + icon.getPreviewItemManager().draw(c); + c.setBitmap(null); + + // Initialize mask + Path mask = new Path(); + Matrix m = new Matrix(); + m.setTranslate(margin, margin); + bg.getClipPath().transform(m, mask); + + ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBitmap, margin, margin); + ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap, + margin - previewShiftX, margin - previewShiftY); + + return new FolderAdaptiveIcon(new ColorDrawable(bg.getBgColor()), foreground, badge, mask); + } + + /** + * A simple drawable which draws a bitmap at a fixed position irrespective of the bounds + */ + private static class ShiftedBitmapDrawable extends Drawable { + + private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); + private final Bitmap mBitmap; + private final float mShiftX; + private final float mShiftY; + + ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) { + mBitmap = bitmap; + mShiftX = shiftX; + mShiftY = shiftY; + } + + @Override + public void draw(Canvas canvas) { + canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint); + } + + @Override + public void setAlpha(int i) { } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + mPaint.setColorFilter(colorFilter); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + } +} diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 84ec18410..6533b0463 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -440,6 +440,14 @@ public class FolderIcon extends FrameLayout implements FolderListener { invalidate(); } + public PreviewBackground getFolderBackground() { + return mBackground; + } + + public PreviewItemManager getPreviewItemManager() { + return mPreviewItemManager; + } + @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); @@ -463,14 +471,11 @@ public class FolderIcon extends FrameLayout implements FolderListener { } else { saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG); if (mPreviewLayoutRule.clipToBackground()) { - mBackground.clipCanvasSoftware(canvas, Region.Op.INTERSECT); + canvas.clipPath(mBackground.getClipPath(), Region.Op.INTERSECT); } } - // The items are drawn in coordinates relative to the preview offset - canvas.translate(mBackground.basePreviewOffsetX, mBackground.basePreviewOffsetY); mPreviewItemManager.draw(canvas); - canvas.translate(-mBackground.basePreviewOffsetX, -mBackground.basePreviewOffsetY); if (mPreviewLayoutRule.clipToBackground() && canvas.isHardwareAccelerated()) { mBackground.clipCanvasHardware(canvas); @@ -481,6 +486,10 @@ public class FolderIcon extends FrameLayout implements FolderListener { mBackground.drawBackgroundStroke(canvas); } + drawBadge(canvas); + } + + public void drawBadge(Canvas canvas) { if ((mBadgeInfo != null && mBadgeInfo.hasBadge()) || mBadgeScale > 0) { int offsetX = mBackground.getOffsetX(); int offsetY = mBackground.getOffsetY(); diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java index 61490eee8..eba5d984d 100644 --- a/src/com/android/launcher3/folder/PreviewBackground.java +++ b/src/com/android/launcher3/folder/PreviewBackground.java @@ -195,19 +195,28 @@ public class PreviewBackground { invalidate(); } + public int getBgColor() { + int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier); + return ColorUtils.setAlphaComponent(mBgColor, alpha); + } + public void drawBackground(Canvas canvas) { mPaint.setStyle(Paint.Style.FILL); - int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier); - mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, alpha)); + mPaint.setColor(getBgColor()); drawCircle(canvas, 0 /* deltaRadius */); - // Draw shadow. + drawShadow(canvas); + } + + public void drawShadow(Canvas canvas) { if (mShadowShader == null) { return; } + float radius = getScaledRadius(); float shadowRadius = radius + mStrokeWidth; + mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(Color.BLACK); int offsetX = getOffsetX(); int offsetY = getOffsetY(); @@ -219,7 +228,7 @@ public class PreviewBackground { } else { saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG); - clipCanvasSoftware(canvas, Region.Op.DIFFERENCE); + canvas.clipPath(getClipPath(), Region.Op.DIFFERENCE); } mShaderMatrix.setScale(shadowRadius, shadowRadius); @@ -295,12 +304,11 @@ public class PreviewBackground { radius - deltaRadius, mPaint); } - // It is the callers responsibility to save and restore the canvas layers. - void clipCanvasSoftware(Canvas canvas, Region.Op op) { + public Path getClipPath() { mPath.reset(); float r = getScaledRadius(); mPath.addCircle(r + getOffsetX(), r + getOffsetY(), r, Path.Direction.CW); - canvas.clipPath(mPath, op); + return mPath; } // It is the callers responsibility to save and restore the canvas layers. diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java index 2ecb54ca8..2d979a661 100644 --- a/src/com/android/launcher3/folder/PreviewItemManager.java +++ b/src/com/android/launcher3/folder/PreviewItemManager.java @@ -146,6 +146,10 @@ public class PreviewItemManager { } public void draw(Canvas canvas) { + // The items are drawn in coordinates relative to the preview offset + PreviewBackground bg = mIcon.getFolderBackground(); + canvas.translate(bg.basePreviewOffsetX, bg.basePreviewOffsetY); + float firstPageItemsTransX = 0; if (mShouldSlideInFirstPage) { drawParams(canvas, mCurrentPageParams, mCurrentPageItemsTransX); @@ -154,6 +158,7 @@ public class PreviewItemManager { } drawParams(canvas, mFirstPageParams, firstPageItemsTransX); + canvas.translate(-bg.basePreviewOffsetX, -bg.basePreviewOffsetY); } public void onParamsChanged() { diff --git a/src/com/android/launcher3/graphics/GradientView.java b/src/com/android/launcher3/graphics/GradientView.java index 678396df1..5455b43ec 100644 --- a/src/com/android/launcher3/graphics/GradientView.java +++ b/src/com/android/launcher3/graphics/GradientView.java @@ -27,6 +27,7 @@ import android.graphics.RectF; import android.graphics.Shader; import android.support.v4.graphics.ColorUtils; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.Interpolator; @@ -46,7 +47,6 @@ public class GradientView extends View implements WallpaperColorInfo.OnChangeLis private static final int DEFAULT_COLOR = Color.WHITE; private static final int ALPHA_MASK_HEIGHT_DP = 500; private static final int ALPHA_MASK_WIDTH_DP = 2; - private static final int ALPHA_COLORS = 0xBF; private static final boolean DEBUG = false; private final Bitmap mAlphaGradientMask; @@ -62,7 +62,7 @@ public class GradientView extends View implements WallpaperColorInfo.OnChangeLis private final Paint mPaintNoScrim = new Paint(); private float mProgress; private final int mMaskHeight, mMaskWidth; - private final Context mAppContext; + private final int mAlphaColors; private final Paint mDebugPaint = DEBUG ? new Paint() : null; private final Interpolator mAccelerator = new AccelerateInterpolator(); private final float mAlphaStart; @@ -71,15 +71,14 @@ public class GradientView extends View implements WallpaperColorInfo.OnChangeLis public GradientView(Context context, AttributeSet attrs) { super(context, attrs); - this.mAppContext = context.getApplicationContext(); - this.mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_HEIGHT_DP, - mAppContext.getResources().getDisplayMetrics()); - this.mMaskWidth = Utilities.pxFromDp(ALPHA_MASK_WIDTH_DP, - mAppContext.getResources().getDisplayMetrics()); + DisplayMetrics dm = getResources().getDisplayMetrics(); + this.mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_HEIGHT_DP, dm); + this.mMaskWidth = Utilities.pxFromDp(ALPHA_MASK_WIDTH_DP, dm); Launcher launcher = Launcher.getLauncher(context); this.mAlphaStart = launcher.getDeviceProfile().isVerticalBarLayout() ? 0 : 100; this.mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor); this.mWallpaperColorInfo = WallpaperColorInfo.getInstance(launcher); + mAlphaColors = getResources().getInteger(R.integer.extracted_color_gradient_alpha); updateColors(); mAlphaGradientMask = createDitheredAlphaMask(); } @@ -104,9 +103,9 @@ public class GradientView extends View implements WallpaperColorInfo.OnChangeLis private void updateColors() { this.mColor1 = ColorUtils.setAlphaComponent(mWallpaperColorInfo.getMainColor(), - ALPHA_COLORS); + mAlphaColors); this.mColor2 = ColorUtils.setAlphaComponent(mWallpaperColorInfo.getSecondaryColor(), - ALPHA_COLORS); + mAlphaColors); if (mWidth + mHeight > 0) { createRadialShader(); } diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java index 4c83e9ac2..f7f8ef18f 100644 --- a/src/com/android/launcher3/logging/FileLog.java +++ b/src/com/android/launcher3/logging/FileLog.java @@ -29,6 +29,8 @@ import java.util.concurrent.TimeUnit; */ public final class FileLog { + protected static final boolean ENABLED = + FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE; private static final String FILE_NAME_PREFIX = "log-"; private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); @@ -39,7 +41,7 @@ public final class FileLog { private static File sLogsDirectory = null; public static void setDir(File logsDir) { - if (FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE) { + if (ENABLED) { synchronized (DATE_FORMAT) { // If the target directory changes, stop any active thread. if (sHandler != null && !logsDir.equals(sLogsDirectory)) { @@ -76,7 +78,7 @@ public final class FileLog { } public static void print(String tag, String msg, Exception e) { - if (!FeatureFlags.IS_DOGFOOD_BUILD) { + if (!ENABLED) { return; } String out = String.format("%s %s %s", DATE_FORMAT.format(new Date()), tag, msg); @@ -102,7 +104,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 (!FeatureFlags.IS_DOGFOOD_BUILD) { + if (!ENABLED) { return; } CountDownLatch latch = new CountDownLatch(1); @@ -135,7 +137,7 @@ public final class FileLog { @Override public boolean handleMessage(Message msg) { - if (sLogsDirectory == null || !FeatureFlags.IS_DOGFOOD_BUILD) { + if (sLogsDirectory == null || !ENABLED) { return true; } switch (msg.what) { diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java index 72a083b9e..ebb69c43b 100644 --- a/src/com/android/launcher3/logging/LoggerUtils.java +++ b/src/com/android/launcher3/logging/LoggerUtils.java @@ -25,6 +25,7 @@ import com.android.launcher3.InfoDropTarget; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.UninstallDropTarget; +import com.android.launcher3.userevent.nano.LauncherLogExtensions.TargetExtension; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType; @@ -159,6 +160,13 @@ public class LoggerUtils { return t; } + public static Target newTarget(int targetType, TargetExtension extension) { + Target t = new Target(); + t.type = targetType; + t.extension = extension; + return t; + } + public static Target newTarget(int targetType) { Target t = new Target(); t.type = targetType; diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 5bad436f8..c56325ad5 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -548,6 +548,11 @@ public class LoaderTask implements Runnable { break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: + if (FeatureFlags.GO_DISABLE_WIDGETS) { + c.markDeleted("Only legacy shortcuts can have null package"); + continue; + } + // Follow through case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: // Read all Launcher-specific widget details boolean customWidget = c.itemType == diff --git a/src/com/android/launcher3/notification/FlingAnimationUtils.java b/src/com/android/launcher3/notification/FlingAnimationUtils.java deleted file mode 100644 index a1f7e49c0..000000000 --- a/src/com/android/launcher3/notification/FlingAnimationUtils.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.notification; - -import android.animation.Animator; -import android.content.Context; -import android.view.ViewPropertyAnimator; -import android.view.animation.Interpolator; -import android.view.animation.PathInterpolator; - -/** - * Utility class to calculate general fling animation when the finger is released. - * - * This class was copied from com.android.systemui.statusbar. - */ -public class FlingAnimationUtils { - - private static final float LINEAR_OUT_SLOW_IN_X2 = 0.35f; - private static final float LINEAR_OUT_SLOW_IN_X2_MAX = 0.68f; - private static final float LINEAR_OUT_FASTER_IN_X2 = 0.5f; - private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.4f; - private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 0.5f; - private static final float MIN_VELOCITY_DP_PER_SECOND = 250; - private static final float HIGH_VELOCITY_DP_PER_SECOND = 3000; - - private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 0.75f; - private final float mSpeedUpFactor; - private final float mY2; - - private float mMinVelocityPxPerSecond; - private float mMaxLengthSeconds; - private float mHighVelocityPxPerSecond; - private float mLinearOutSlowInX2; - - private AnimatorProperties mAnimatorProperties = new AnimatorProperties(); - private PathInterpolator mInterpolator; - private float mCachedStartGradient = -1; - private float mCachedVelocityFactor = -1; - - public FlingAnimationUtils(Context ctx, float maxLengthSeconds) { - this(ctx, maxLengthSeconds, 0.0f); - } - - /** - * @param maxLengthSeconds the longest duration an animation can become in seconds - * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards - * the end of the animation. 0 means it's at the beginning and no - * acceleration will take place. - */ - public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor) { - this(ctx, maxLengthSeconds, speedUpFactor, -1.0f, 1.0f); - } - - /** - * @param maxLengthSeconds the longest duration an animation can become in seconds - * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards - * the end of the animation. 0 means it's at the beginning and no - * acceleration will take place. - * @param x2 the x value to take for the second point of the bezier spline. If a value below 0 - * is provided, the value is automatically calculated. - * @param y2 the y value to take for the second point of the bezier spline - */ - public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor, float x2, - float y2) { - mMaxLengthSeconds = maxLengthSeconds; - mSpeedUpFactor = speedUpFactor; - if (x2 < 0) { - mLinearOutSlowInX2 = interpolate(LINEAR_OUT_SLOW_IN_X2, - LINEAR_OUT_SLOW_IN_X2_MAX, - mSpeedUpFactor); - } else { - mLinearOutSlowInX2 = x2; - } - mY2 = y2; - - mMinVelocityPxPerSecond - = MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density; - mHighVelocityPxPerSecond - = HIGH_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density; - } - - private static float interpolate(float start, float end, float amount) { - return start * (1.0f - amount) + end * amount; - } - - /** - * Applies the interpolator and length to the animator, such that the fling animation is - * consistent with the finger motion. - * - * @param animator the animator to apply - * @param currValue the current value - * @param endValue the end value of the animator - * @param velocity the current velocity of the motion - */ - public void apply(Animator animator, float currValue, float endValue, float velocity) { - apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue)); - } - - /** - * Applies the interpolator and length to the animator, such that the fling animation is - * consistent with the finger motion. - * - * @param animator the animator to apply - * @param currValue the current value - * @param endValue the end value of the animator - * @param velocity the current velocity of the motion - */ - public void apply(ViewPropertyAnimator animator, float currValue, float endValue, - float velocity) { - apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue)); - } - - /** - * Applies the interpolator and length to the animator, such that the fling animation is - * consistent with the finger motion. - * - * @param animator the animator to apply - * @param currValue the current value - * @param endValue the end value of the animator - * @param velocity the current velocity of the motion - * @param maxDistance the maximum distance for this interaction; the maximum animation length - * gets multiplied by the ratio between the actual distance and this value - */ - public void apply(Animator animator, float currValue, float endValue, float velocity, - float maxDistance) { - AnimatorProperties properties = getProperties(currValue, endValue, velocity, - maxDistance); - animator.setDuration(properties.duration); - animator.setInterpolator(properties.interpolator); - } - - /** - * Applies the interpolator and length to the animator, such that the fling animation is - * consistent with the finger motion. - * - * @param animator the animator to apply - * @param currValue the current value - * @param endValue the end value of the animator - * @param velocity the current velocity of the motion - * @param maxDistance the maximum distance for this interaction; the maximum animation length - * gets multiplied by the ratio between the actual distance and this value - */ - public void apply(ViewPropertyAnimator animator, float currValue, float endValue, - float velocity, float maxDistance) { - AnimatorProperties properties = getProperties(currValue, endValue, velocity, - maxDistance); - animator.setDuration(properties.duration); - animator.setInterpolator(properties.interpolator); - } - - private AnimatorProperties getProperties(float currValue, - float endValue, float velocity, float maxDistance) { - float maxLengthSeconds = (float) (mMaxLengthSeconds - * Math.sqrt(Math.abs(endValue - currValue) / maxDistance)); - float diff = Math.abs(endValue - currValue); - float velAbs = Math.abs(velocity); - float velocityFactor = mSpeedUpFactor == 0.0f - ? 1.0f : Math.min(velAbs / HIGH_VELOCITY_DP_PER_SECOND, 1.0f); - float startGradient = interpolate(LINEAR_OUT_SLOW_IN_START_GRADIENT, - mY2 / mLinearOutSlowInX2, velocityFactor); - float durationSeconds = startGradient * diff / velAbs; - Interpolator slowInInterpolator = getInterpolator(startGradient, velocityFactor); - if (durationSeconds <= maxLengthSeconds) { - mAnimatorProperties.interpolator = slowInInterpolator; - } else if (velAbs >= mMinVelocityPxPerSecond) { - - // Cross fade between fast-out-slow-in and linear interpolator with current velocity. - durationSeconds = maxLengthSeconds; - VelocityInterpolator velocityInterpolator - = new VelocityInterpolator(durationSeconds, velAbs, diff); - InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator( - velocityInterpolator, slowInInterpolator, Interpolators.LINEAR_OUT_SLOW_IN); - mAnimatorProperties.interpolator = superInterpolator; - } else { - - // Just use a normal interpolator which doesn't take the velocity into account. - durationSeconds = maxLengthSeconds; - mAnimatorProperties.interpolator = Interpolators.FAST_OUT_SLOW_IN; - } - mAnimatorProperties.duration = (long) (durationSeconds * 1000); - return mAnimatorProperties; - } - - private Interpolator getInterpolator(float startGradient, float velocityFactor) { - if (startGradient != mCachedStartGradient - || velocityFactor != mCachedVelocityFactor) { - float speedup = mSpeedUpFactor * (1.0f - velocityFactor); - mInterpolator = new PathInterpolator(speedup, - speedup * startGradient, - mLinearOutSlowInX2, mY2); - mCachedStartGradient = startGradient; - mCachedVelocityFactor = velocityFactor; - } - return mInterpolator; - } - - /** - * Applies the interpolator and length to the animator, such that the fling animation is - * consistent with the finger motion for the case when the animation is making something - * disappear. - * - * @param animator the animator to apply - * @param currValue the current value - * @param endValue the end value of the animator - * @param velocity the current velocity of the motion - * @param maxDistance the maximum distance for this interaction; the maximum animation length - * gets multiplied by the ratio between the actual distance and this value - */ - public void applyDismissing(Animator animator, float currValue, float endValue, - float velocity, float maxDistance) { - AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity, - maxDistance); - animator.setDuration(properties.duration); - animator.setInterpolator(properties.interpolator); - } - - /** - * Applies the interpolator and length to the animator, such that the fling animation is - * consistent with the finger motion for the case when the animation is making something - * disappear. - * - * @param animator the animator to apply - * @param currValue the current value - * @param endValue the end value of the animator - * @param velocity the current velocity of the motion - * @param maxDistance the maximum distance for this interaction; the maximum animation length - * gets multiplied by the ratio between the actual distance and this value - */ - public void applyDismissing(ViewPropertyAnimator animator, float currValue, float endValue, - float velocity, float maxDistance) { - AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity, - maxDistance); - animator.setDuration(properties.duration); - animator.setInterpolator(properties.interpolator); - } - - private AnimatorProperties getDismissingProperties(float currValue, float endValue, - float velocity, float maxDistance) { - float maxLengthSeconds = (float) (mMaxLengthSeconds - * Math.pow(Math.abs(endValue - currValue) / maxDistance, 0.5f)); - float diff = Math.abs(endValue - currValue); - float velAbs = Math.abs(velocity); - float y2 = calculateLinearOutFasterInY2(velAbs); - - float startGradient = y2 / LINEAR_OUT_FASTER_IN_X2; - Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, LINEAR_OUT_FASTER_IN_X2, y2); - float durationSeconds = startGradient * diff / velAbs; - if (durationSeconds <= maxLengthSeconds) { - mAnimatorProperties.interpolator = mLinearOutFasterIn; - } else if (velAbs >= mMinVelocityPxPerSecond) { - - // Cross fade between linear-out-faster-in and linear interpolator with current - // velocity. - durationSeconds = maxLengthSeconds; - VelocityInterpolator velocityInterpolator - = new VelocityInterpolator(durationSeconds, velAbs, diff); - InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator( - velocityInterpolator, mLinearOutFasterIn, Interpolators.LINEAR_OUT_SLOW_IN); - mAnimatorProperties.interpolator = superInterpolator; - } else { - - // Just use a normal interpolator which doesn't take the velocity into account. - durationSeconds = maxLengthSeconds; - mAnimatorProperties.interpolator = Interpolators.FAST_OUT_LINEAR_IN; - } - mAnimatorProperties.duration = (long) (durationSeconds * 1000); - return mAnimatorProperties; - } - - /** - * Calculates the y2 control point for a linear-out-faster-in path interpolator depending on the - * velocity. The faster the velocity, the more "linear" the interpolator gets. - * - * @param velocity the velocity of the gesture. - * @return the y2 control point for a cubic bezier path interpolator - */ - private float calculateLinearOutFasterInY2(float velocity) { - float t = (velocity - mMinVelocityPxPerSecond) - / (mHighVelocityPxPerSecond - mMinVelocityPxPerSecond); - t = Math.max(0, Math.min(1, t)); - return (1 - t) * LINEAR_OUT_FASTER_IN_Y2_MIN + t * LINEAR_OUT_FASTER_IN_Y2_MAX; - } - - /** - * @return the minimum velocity a gesture needs to have to be considered a fling - */ - public float getMinVelocityPxPerSecond() { - return mMinVelocityPxPerSecond; - } - - /** - * An interpolator which interpolates two interpolators with an interpolator. - */ - private static final class InterpolatorInterpolator implements Interpolator { - - private Interpolator mInterpolator1; - private Interpolator mInterpolator2; - private Interpolator mCrossfader; - - InterpolatorInterpolator(Interpolator interpolator1, Interpolator interpolator2, - Interpolator crossfader) { - mInterpolator1 = interpolator1; - mInterpolator2 = interpolator2; - mCrossfader = crossfader; - } - - @Override - public float getInterpolation(float input) { - float t = mCrossfader.getInterpolation(input); - return (1 - t) * mInterpolator1.getInterpolation(input) - + t * mInterpolator2.getInterpolation(input); - } - } - - /** - * An interpolator which interpolates with a fixed velocity. - */ - private static final class VelocityInterpolator implements Interpolator { - - private float mDurationSeconds; - private float mVelocity; - private float mDiff; - - private VelocityInterpolator(float durationSeconds, float velocity, float diff) { - mDurationSeconds = durationSeconds; - mVelocity = velocity; - mDiff = diff; - } - - @Override - public float getInterpolation(float input) { - float time = input * mDurationSeconds; - return time * mVelocity / mDiff; - } - } - - private static class AnimatorProperties { - Interpolator interpolator; - long duration; - } - -} diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java index 11f6aa081..78c64d7da 100644 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ b/src/com/android/launcher3/notification/NotificationItemView.java @@ -37,6 +37,7 @@ import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.graphics.IconPalette; import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; import com.android.launcher3.popup.PopupItemView; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.Themes; @@ -56,7 +57,7 @@ public class NotificationItemView extends PopupItemView implements LogContainerP private TextView mHeaderCount; private NotificationMainView mMainView; private NotificationFooterLayout mFooter; - private SwipeHelper mSwipeHelper; + private SwipeDetector mSwipeDetector; private boolean mAnimatingNextIcon; private int mNotificationHeaderTextColor = Notification.COLOR_DEFAULT; @@ -75,12 +76,14 @@ public class NotificationItemView extends PopupItemView implements LogContainerP @Override protected void onFinishInflate() { super.onFinishInflate(); - mHeaderText = (TextView) findViewById(R.id.notification_text); - mHeaderCount = (TextView) findViewById(R.id.notification_count); - mMainView = (NotificationMainView) findViewById(R.id.main_view); - mFooter = (NotificationFooterLayout) findViewById(R.id.footer); - mSwipeHelper = new SwipeHelper(SwipeHelper.X, mMainView, getContext()); - mSwipeHelper.setDisableHardwareLayers(true); + mHeaderText = findViewById(R.id.notification_text); + mHeaderCount = findViewById(R.id.notification_count); + mMainView = findViewById(R.id.main_view); + mFooter = findViewById(R.id.footer); + + mSwipeDetector = new SwipeDetector(getContext(), mMainView, SwipeDetector.HORIZONTAL); + mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false); + mMainView.setSwipeDetector(mSwipeDetector); } public NotificationMainView getMainView() { @@ -136,7 +139,8 @@ public class NotificationItemView extends PopupItemView implements LogContainerP return false; } getParent().requestDisallowInterceptTouchEvent(true); - return mSwipeHelper.onInterceptTouchEvent(ev); + mSwipeDetector.onTouchEvent(ev); + return mSwipeDetector.isDraggingOrSettling(); } @Override @@ -145,7 +149,7 @@ public class NotificationItemView extends PopupItemView implements LogContainerP // The notification hasn't been populated yet. return false; } - return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev); + return mSwipeDetector.onTouchEvent(ev) || super.onTouchEvent(ev); } public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) { diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java index 73d89aa18..6a7098915 100644 --- a/src/com/android/launcher3/notification/NotificationListener.java +++ b/src/com/android/launcher3/notification/NotificationListener.java @@ -30,15 +30,20 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Pair; + import com.android.launcher3.LauncherModel; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.SettingsObserver; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; +import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING; + /** * A {@link NotificationListenerService} that sends updates to its * {@link NotificationsChangedListener} when notifications are posted or canceled, @@ -57,12 +62,14 @@ public class NotificationListener extends NotificationListenerService { private static NotificationListener sNotificationListenerInstance = null; private static NotificationsChangedListener sNotificationsChangedListener; private static boolean sIsConnected; + private static boolean sIsCreated; private final Handler mWorkerHandler; private final Handler mUiHandler; - private final Ranking mTempRanking = new Ranking(); + private SettingsObserver mNotificationBadgingObserver; + private final Handler.Callback mWorkerCallback = new Handler.Callback() { @Override public boolean handleMessage(Message message) { @@ -77,7 +84,7 @@ public class NotificationListener extends NotificationListenerService { List<StatusBarNotification> activeNotifications; if (sIsConnected) { try { - activeNotifications = filterNotifications(getActiveNotifications()); + activeNotifications = filterNotifications(getActiveNotifications()); } catch (SecurityException ex) { Log.e(TAG, "SecurityException: failed to fetch notifications"); activeNotifications = new ArrayList<StatusBarNotification>(); @@ -130,6 +137,28 @@ public class NotificationListener extends NotificationListenerService { sNotificationListenerInstance = this; } + @Override + public void onCreate() { + super.onCreate(); + sIsCreated = true; + mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) { + @Override + public void onSettingChanged(boolean isNotificationBadgingEnabled) { + if (!isNotificationBadgingEnabled) { + requestUnbind(); + } + } + }; + mNotificationBadgingObserver.register(NOTIFICATION_BADGING); + } + + @Override + public void onDestroy() { + super.onDestroy(); + sIsCreated = false; + mNotificationBadgingObserver.unregister(); + } + public static @Nullable NotificationListener getInstanceIfConnected() { return sIsConnected ? sNotificationListenerInstance : null; } @@ -143,6 +172,11 @@ public class NotificationListener extends NotificationListenerService { NotificationListener notificationListener = getInstanceIfConnected(); if (notificationListener != null) { notificationListener.onNotificationFullRefresh(); + } else if (!sIsCreated && sNotificationsChangedListener != null) { + // User turned off badging globally, so we unbound this service; + // tell the listener that there are no notifications to remove dots. + sNotificationsChangedListener.onNotificationFullRefresh( + Collections.<StatusBarNotification>emptyList()); } } @@ -205,7 +239,7 @@ public class NotificationListener extends NotificationListenerService { .getActiveNotifications(NotificationKeyData.extractKeysOnly(keys) .toArray(new String[keys.size()])); return notifications == null - ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications); + ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications); } /** diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java index 9b8dd648f..5aff28db4 100644 --- a/src/com/android/launcher3/notification/NotificationMainView.java +++ b/src/com/android/launcher3/notification/NotificationMainView.java @@ -23,15 +23,17 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.RippleDrawable; import android.text.TextUtils; import android.util.AttributeSet; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.widget.FrameLayout; import android.widget.TextView; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.R; +import com.android.launcher3.touch.OverScroll; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.Themes; @@ -39,7 +41,7 @@ import com.android.launcher3.util.Themes; * A {@link android.widget.FrameLayout} that contains a single notification, * e.g. icon + title + text. */ -public class NotificationMainView extends FrameLayout implements SwipeHelper.Callback { +public class NotificationMainView extends FrameLayout implements SwipeDetector.Listener { private NotificationInfo mNotificationInfo; private ViewGroup mTextAndBackground; @@ -47,6 +49,8 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal private TextView mTitleView; private TextView mTextView; + private SwipeDetector mSwipeDetector; + public NotificationMainView(Context context) { this(context, null, 0); } @@ -78,6 +82,10 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal applyNotificationInfo(mainNotification, iconView, false); } + public void setSwipeDetector(SwipeDetector swipeDetector) { + mSwipeDetector = swipeDetector; + } + /** * Sets the content of this view, animating it after a new icon shifts up if necessary. */ @@ -113,29 +121,11 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal } - // SwipeHelper.Callback's - - @Override - public View getChildAtPosition(MotionEvent ev) { - return this; - } - - @Override - public boolean canChildBeDismissed(View v) { + public boolean canChildBeDismissed() { return mNotificationInfo != null && mNotificationInfo.dismissable; } - @Override - public boolean isAntiFalsingNeeded() { - return false; - } - - @Override - public void onBeginDrag(View v) { - } - - @Override - public void onChildDismissed(View v) { + public void onChildDismissed() { Launcher launcher = Launcher.getLauncher(getContext()); launcher.getPopupDataProvider().cancelNotification( mNotificationInfo.notificationKey); @@ -145,22 +135,55 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal LauncherLogProto.ItemType.NOTIFICATION); } + // SwipeDetector.Listener's @Override - public void onDragCancelled(View v) { - } + public void onDragStart(boolean start) { } - @Override - public void onChildSnappedBack(View animView, float targetLeft) { - } @Override - public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) { - // Don't fade out. + public boolean onDrag(float displacement, float velocity) { + setTranslationX(canChildBeDismissed() + ? displacement : OverScroll.dampedScroll(displacement, getWidth())); + animate().cancel(); return true; } @Override - public float getFalsingThresholdFactor() { - return 1; + public void onDragEnd(float velocity, boolean fling) { + final boolean willExit; + final float endTranslation; + + if (!canChildBeDismissed()) { + willExit = false; + endTranslation = 0; + } else if (fling) { + willExit = true; + endTranslation = velocity < 0 ? - getWidth() : getWidth(); + } else if (Math.abs(getTranslationX()) > getWidth() / 2) { + willExit = true; + endTranslation = (getTranslationX() < 0 ? -getWidth() : getWidth()); + } else { + willExit = false; + endTranslation = 0; + } + + SwipeDetector.ScrollInterpolator interpolator = new SwipeDetector.ScrollInterpolator(); + interpolator.setVelocityAtZero(velocity); + + long duration = SwipeDetector.calculateDuration(velocity, + (endTranslation - getTranslationX()) / getWidth()); + animate() + .setDuration(duration) + .setInterpolator(interpolator) + .translationX(endTranslation) + .withEndAction(new Runnable() { + @Override + public void run() { + mSwipeDetector.finishedScrolling(); + if (willExit) { + onChildDismissed(); + } + } + }).start(); } } diff --git a/src/com/android/launcher3/notification/SwipeHelper.java b/src/com/android/launcher3/notification/SwipeHelper.java deleted file mode 100644 index ebbe5fc6a..000000000 --- a/src/com/android/launcher3/notification/SwipeHelper.java +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.notification; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.content.Context; -import android.graphics.RectF; -import android.os.Handler; -import android.util.ArrayMap; -import android.util.Log; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.accessibility.AccessibilityEvent; -import com.android.launcher3.R; - -/** - * This class was copied from com.android.systemui. - */ -public class SwipeHelper { - private static final String TAG = "SwipeHelper"; - private static final boolean DEBUG_INVALIDATE = false; - private static final boolean SLOW_ANIMATIONS = false; // DEBUG; - private static final boolean CONSTRAIN_SWIPE = true; - private static final boolean FADE_OUT_DURING_SWIPE = true; - private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true; - - public static final int X = 0; - public static final int Y = 1; - - private static final float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec - private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms - private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms - private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec - private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms - - static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width - // beyond which swipe progress->0 - private float mMinSwipeProgress = 0f; - private float mMaxSwipeProgress = 1f; - - private final FlingAnimationUtils mFlingAnimationUtils; - private float mPagingTouchSlop; - private final Callback mCallback; - private final Handler mHandler; - private final int mSwipeDirection; - private final VelocityTracker mVelocityTracker; - - private float mInitialTouchPos; - private float mPerpendicularInitialTouchPos; - private boolean mDragging; - private boolean mSnappingChild; - private View mCurrView; - private boolean mCanCurrViewBeDimissed; - private float mDensityScale; - private float mTranslation = 0; - - private boolean mLongPressSent; - private LongPressListener mLongPressListener; - private Runnable mWatchLongPress; - private final long mLongPressTimeout; - - final private int[] mTmpPos = new int[2]; - private final int mFalsingThreshold; - private boolean mTouchAboveFalsingThreshold; - private boolean mDisableHwLayers; - - private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>(); - - public SwipeHelper(int swipeDirection, Callback callback, Context context) { - mCallback = callback; - mHandler = new Handler(); - mSwipeDirection = swipeDirection; - mVelocityTracker = VelocityTracker.obtain(); - mDensityScale = context.getResources().getDisplayMetrics().density; - mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); - - mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press! - mFalsingThreshold = context.getResources().getDimensionPixelSize( - R.dimen.swipe_helper_falsing_threshold); - mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f); - } - - public void setLongPressListener(LongPressListener listener) { - mLongPressListener = listener; - } - - public void setDensityScale(float densityScale) { - mDensityScale = densityScale; - } - - public void setPagingTouchSlop(float pagingTouchSlop) { - mPagingTouchSlop = pagingTouchSlop; - } - - public void setDisableHardwareLayers(boolean disableHwLayers) { - mDisableHwLayers = disableHwLayers; - } - - private float getPos(MotionEvent ev) { - return mSwipeDirection == X ? ev.getX() : ev.getY(); - } - - private float getPerpendicularPos(MotionEvent ev) { - return mSwipeDirection == X ? ev.getY() : ev.getX(); - } - - protected float getTranslation(View v) { - return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY(); - } - - private float getVelocity(VelocityTracker vt) { - return mSwipeDirection == X ? vt.getXVelocity() : - vt.getYVelocity(); - } - - protected ObjectAnimator createTranslationAnimation(View v, float newPos) { - ObjectAnimator anim = ObjectAnimator.ofFloat(v, - mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos); - return anim; - } - - private float getPerpendicularVelocity(VelocityTracker vt) { - return mSwipeDirection == X ? vt.getYVelocity() : - vt.getXVelocity(); - } - - protected Animator getViewTranslationAnimator(View v, float target, - AnimatorUpdateListener listener) { - ObjectAnimator anim = createTranslationAnimation(v, target); - if (listener != null) { - anim.addUpdateListener(listener); - } - return anim; - } - - protected void setTranslation(View v, float translate) { - if (v == null) { - return; - } - if (mSwipeDirection == X) { - v.setTranslationX(translate); - } else { - v.setTranslationY(translate); - } - } - - protected float getSize(View v) { - return mSwipeDirection == X ? v.getMeasuredWidth() : - v.getMeasuredHeight(); - } - - public void setMinSwipeProgress(float minSwipeProgress) { - mMinSwipeProgress = minSwipeProgress; - } - - public void setMaxSwipeProgress(float maxSwipeProgress) { - mMaxSwipeProgress = maxSwipeProgress; - } - - private float getSwipeProgressForOffset(View view, float translation) { - float viewSize = getSize(view); - float result = Math.abs(translation / viewSize); - return Math.min(Math.max(mMinSwipeProgress, result), mMaxSwipeProgress); - } - - private float getSwipeAlpha(float progress) { - return Math.min(0, Math.max(1, progress / SWIPE_PROGRESS_FADE_END)); - } - - private void updateSwipeProgressFromOffset(View animView, boolean dismissable) { - updateSwipeProgressFromOffset(animView, dismissable, getTranslation(animView)); - } - - private void updateSwipeProgressFromOffset(View animView, boolean dismissable, - float translation) { - float swipeProgress = getSwipeProgressForOffset(animView, translation); - if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) { - if (FADE_OUT_DURING_SWIPE && dismissable) { - float alpha = swipeProgress; - if (!mDisableHwLayers) { - if (alpha != 0f && alpha != 1f) { - animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } else { - animView.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - animView.setAlpha(getSwipeAlpha(swipeProgress)); - } - } - invalidateGlobalRegion(animView); - } - - // invalidate the view's own bounds all the way up the view hierarchy - public static void invalidateGlobalRegion(View view) { - invalidateGlobalRegion( - view, - new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); - } - - // invalidate a rectangle relative to the view's coordinate system all the way up the view - // hierarchy - public static void invalidateGlobalRegion(View view, RectF childBounds) { - //childBounds.offset(view.getTranslationX(), view.getTranslationY()); - if (DEBUG_INVALIDATE) - Log.v(TAG, "-------------"); - while (view.getParent() != null && view.getParent() instanceof View) { - view = (View) view.getParent(); - view.getMatrix().mapRect(childBounds); - view.invalidate((int) Math.floor(childBounds.left), - (int) Math.floor(childBounds.top), - (int) Math.ceil(childBounds.right), - (int) Math.ceil(childBounds.bottom)); - if (DEBUG_INVALIDATE) { - Log.v(TAG, "INVALIDATE(" + (int) Math.floor(childBounds.left) - + "," + (int) Math.floor(childBounds.top) - + "," + (int) Math.ceil(childBounds.right) - + "," + (int) Math.ceil(childBounds.bottom)); - } - } - } - - public void removeLongPressCallback() { - if (mWatchLongPress != null) { - mHandler.removeCallbacks(mWatchLongPress); - mWatchLongPress = null; - } - } - - public boolean onInterceptTouchEvent(final MotionEvent ev) { - final int action = ev.getAction(); - - switch (action) { - case MotionEvent.ACTION_DOWN: - mTouchAboveFalsingThreshold = false; - mDragging = false; - mSnappingChild = false; - mLongPressSent = false; - mVelocityTracker.clear(); - mCurrView = mCallback.getChildAtPosition(ev); - - if (mCurrView != null) { - onDownUpdate(mCurrView); - mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView); - mVelocityTracker.addMovement(ev); - mInitialTouchPos = getPos(ev); - mPerpendicularInitialTouchPos = getPerpendicularPos(ev); - mTranslation = getTranslation(mCurrView); - if (mLongPressListener != null) { - if (mWatchLongPress == null) { - mWatchLongPress = new Runnable() { - @Override - public void run() { - if (mCurrView != null && !mLongPressSent) { - mLongPressSent = true; - mCurrView.sendAccessibilityEvent( - AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); - mCurrView.getLocationOnScreen(mTmpPos); - final int x = (int) ev.getRawX() - mTmpPos[0]; - final int y = (int) ev.getRawY() - mTmpPos[1]; - mLongPressListener.onLongPress(mCurrView, x, y); - } - } - }; - } - mHandler.postDelayed(mWatchLongPress, mLongPressTimeout); - } - } - break; - - case MotionEvent.ACTION_MOVE: - if (mCurrView != null && !mLongPressSent) { - mVelocityTracker.addMovement(ev); - float pos = getPos(ev); - float perpendicularPos = getPerpendicularPos(ev); - float delta = pos - mInitialTouchPos; - float deltaPerpendicular = perpendicularPos - mPerpendicularInitialTouchPos; - if (Math.abs(delta) > mPagingTouchSlop - && Math.abs(delta) > Math.abs(deltaPerpendicular)) { - mCallback.onBeginDrag(mCurrView); - mDragging = true; - mInitialTouchPos = getPos(ev); - mTranslation = getTranslation(mCurrView); - removeLongPressCallback(); - } - } - break; - - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - final boolean captured = (mDragging || mLongPressSent); - mDragging = false; - mCurrView = null; - mLongPressSent = false; - removeLongPressCallback(); - if (captured) return true; - break; - } - return mDragging || mLongPressSent; - } - - /** - * @param view The view to be dismissed - * @param velocity The desired pixels/second speed at which the view should move - * @param useAccelerateInterpolator Should an accelerating Interpolator be used - */ - public void dismissChild(final View view, float velocity, boolean useAccelerateInterpolator) { - dismissChild(view, velocity, null /* endAction */, 0 /* delay */, - useAccelerateInterpolator, 0 /* fixedDuration */, false /* isDismissAll */); - } - - /** - * @param animView The view to be dismissed - * @param velocity The desired pixels/second speed at which the view should move - * @param endAction The action to perform at the end - * @param delay The delay after which we should start - * @param useAccelerateInterpolator Should an accelerating Interpolator be used - * @param fixedDuration If not 0, this exact duration will be taken - */ - public void dismissChild(final View animView, float velocity, final Runnable endAction, - long delay, boolean useAccelerateInterpolator, long fixedDuration, - boolean isDismissAll) { - final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); - float newPos; - boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; - - // if we use the Menu to dismiss an item in landscape, animate up - boolean animateUpForMenu = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll) - && mSwipeDirection == Y; - // if the language is rtl we prefer swiping to the left - boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll) - && isLayoutRtl; - boolean animateLeft = velocity < 0 - || (velocity == 0 && getTranslation(animView) < 0 && !isDismissAll); - - if (animateLeft || animateLeftForRtl || animateUpForMenu) { - newPos = -getSize(animView); - } else { - newPos = getSize(animView); - } - long duration; - if (fixedDuration == 0) { - duration = MAX_ESCAPE_ANIMATION_DURATION; - if (velocity != 0) { - duration = Math.min(duration, - (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math - .abs(velocity)) - ); - } else { - duration = DEFAULT_ESCAPE_ANIMATION_DURATION; - } - } else { - duration = fixedDuration; - } - - if (!mDisableHwLayers) { - animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } - AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { - public void onAnimationUpdate(ValueAnimator animation) { - onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed); - } - }; - - Animator anim = getViewTranslationAnimator(animView, newPos, updateListener); - if (anim == null) { - return; - } - if (useAccelerateInterpolator) { - anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); - anim.setDuration(duration); - } else { - mFlingAnimationUtils.applyDismissing(anim, getTranslation(animView), - newPos, velocity, getSize(animView)); - } - if (delay > 0) { - anim.setStartDelay(delay); - } - anim.addListener(new AnimatorListenerAdapter() { - private boolean mCancelled; - - public void onAnimationCancel(Animator animation) { - mCancelled = true; - } - - public void onAnimationEnd(Animator animation) { - updateSwipeProgressFromOffset(animView, canBeDismissed); - mDismissPendingMap.remove(animView); - if (!mCancelled) { - mCallback.onChildDismissed(animView); - } - if (endAction != null) { - endAction.run(); - } - if (!mDisableHwLayers) { - animView.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - }); - - prepareDismissAnimation(animView, anim); - mDismissPendingMap.put(animView, anim); - anim.start(); - } - - /** - * Called to update the dismiss animation. - */ - protected void prepareDismissAnimation(View view, Animator anim) { - // Do nothing - } - - public void snapChild(final View animView, final float targetLeft, float velocity) { - final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); - AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { - public void onAnimationUpdate(ValueAnimator animation) { - onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed); - } - }; - - Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener); - if (anim == null) { - return; - } - int duration = SNAP_ANIM_LEN; - anim.setDuration(duration); - anim.addListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animator) { - mSnappingChild = false; - updateSwipeProgressFromOffset(animView, canBeDismissed); - mCallback.onChildSnappedBack(animView, targetLeft); - } - }); - prepareSnapBackAnimation(animView, anim); - mSnappingChild = true; - anim.start(); - } - - /** - * Called to update the snap back animation. - */ - protected void prepareSnapBackAnimation(View view, Animator anim) { - // Do nothing - } - - /** - * Called when there's a down event. - */ - public void onDownUpdate(View currView) { - // Do nothing - } - - /** - * Called on a move event. - */ - protected void onMoveUpdate(View view, float totalTranslation, float delta) { - // Do nothing - } - - /** - * Called in {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} when the current - * view is being animated to dismiss or snap. - */ - public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) { - updateSwipeProgressFromOffset(animView, canBeDismissed, value); - } - - private void snapChildInstantly(final View view) { - final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view); - setTranslation(view, 0); - updateSwipeProgressFromOffset(view, canAnimViewBeDismissed); - } - - /** - * Called when a view is updated to be non-dismissable, if the view was being dismissed before - * the update this will handle snapping it back into place. - * - * @param view the view to snap if necessary. - * @param animate whether to animate the snap or not. - * @param targetLeft the target to snap to. - */ - public void snapChildIfNeeded(final View view, boolean animate, float targetLeft) { - if ((mDragging && mCurrView == view) || mSnappingChild) { - return; - } - boolean needToSnap = false; - Animator dismissPendingAnim = mDismissPendingMap.get(view); - if (dismissPendingAnim != null) { - needToSnap = true; - dismissPendingAnim.cancel(); - } else if (getTranslation(view) != 0) { - needToSnap = true; - } - if (needToSnap) { - if (animate) { - snapChild(view, targetLeft, 0.0f /* velocity */); - } else { - snapChildInstantly(view); - } - } - } - - public boolean onTouchEvent(MotionEvent ev) { - if (mLongPressSent) { - return true; - } - - if (!mDragging) { - if (mCallback.getChildAtPosition(ev) != null) { - - // We are dragging directly over a card, make sure that we also catch the gesture - // even if nobody else wants the touch event. - onInterceptTouchEvent(ev); - return true; - } else { - - // We are not doing anything, make sure the long press callback - // is not still ticking like a bomb waiting to go off. - removeLongPressCallback(); - return false; - } - } - - mVelocityTracker.addMovement(ev); - final int action = ev.getAction(); - switch (action) { - case MotionEvent.ACTION_OUTSIDE: - case MotionEvent.ACTION_MOVE: - if (mCurrView != null) { - float delta = getPos(ev) - mInitialTouchPos; - float absDelta = Math.abs(delta); - if (absDelta >= getFalsingThreshold()) { - mTouchAboveFalsingThreshold = true; - } - // don't let items that can't be dismissed be dragged more than - // maxScrollDistance - if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) { - float size = getSize(mCurrView); - float maxScrollDistance = 0.25f * size; - if (absDelta >= size) { - delta = delta > 0 ? maxScrollDistance : -maxScrollDistance; - } else { - delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2)); - } - } - - setTranslation(mCurrView, mTranslation + delta); - updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed); - onMoveUpdate(mCurrView, mTranslation + delta, delta); - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - if (mCurrView == null) { - break; - } - mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, getMaxVelocity()); - float velocity = getVelocity(mVelocityTracker); - - if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) { - if (isDismissGesture(ev)) { - // flingadingy - dismissChild(mCurrView, velocity, - !swipedFastEnough() /* useAccelerateInterpolator */); - } else { - // snappity - mCallback.onDragCancelled(mCurrView); - snapChild(mCurrView, 0 /* leftTarget */, velocity); - } - mCurrView = null; - } - mDragging = false; - break; - } - return true; - } - - private int getFalsingThreshold() { - float factor = mCallback.getFalsingThresholdFactor(); - return (int) (mFalsingThreshold * factor); - } - - private float getMaxVelocity() { - return MAX_DISMISS_VELOCITY * mDensityScale; - } - - protected float getEscapeVelocity() { - return getUnscaledEscapeVelocity() * mDensityScale; - } - - protected float getUnscaledEscapeVelocity() { - return SWIPE_ESCAPE_VELOCITY; - } - - protected long getMaxEscapeAnimDuration() { - return MAX_ESCAPE_ANIMATION_DURATION; - } - - protected boolean swipedFarEnough() { - float translation = getTranslation(mCurrView); - return DISMISS_IF_SWIPED_FAR_ENOUGH && Math.abs(translation) > 0.4 * getSize(mCurrView); - } - - protected boolean isDismissGesture(MotionEvent ev) { - boolean falsingDetected = mCallback.isAntiFalsingNeeded() && !mTouchAboveFalsingThreshold; - return !falsingDetected && (swipedFastEnough() || swipedFarEnough()) - && ev.getActionMasked() == MotionEvent.ACTION_UP - && mCallback.canChildBeDismissed(mCurrView); - } - - protected boolean swipedFastEnough() { - float velocity = getVelocity(mVelocityTracker); - float translation = getTranslation(mCurrView); - boolean ret = (Math.abs(velocity) > getEscapeVelocity()) - && (velocity > 0) == (translation > 0); - return ret; - } - - protected boolean handleUpEvent(MotionEvent ev, View animView, float velocity, - float translation) { - return false; - } - - public interface Callback { - View getChildAtPosition(MotionEvent ev); - - boolean canChildBeDismissed(View v); - - boolean isAntiFalsingNeeded(); - - void onBeginDrag(View v); - - void onChildDismissed(View v); - - void onDragCancelled(View v); - - /** - * Called when the child is snapped to a position. - * - * @param animView the view that was snapped. - * @param targetLeft the left position the view was snapped to. - */ - void onChildSnappedBack(View animView, float targetLeft); - - /** - * Updates the swipe progress on a child. - * - * @return if true, prevents the default alpha fading. - */ - boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress); - - /** - * @return The factor the falsing threshold should be multiplied with - */ - float getFalsingThresholdFactor(); - } - - /** - * Equivalent to View.OnLongClickListener with coordinates - */ - public interface LongPressListener { - /** - * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates - * @return whether the longpress was handled - */ - boolean onLongPress(View v, int x, int y); - } -}
\ No newline at end of file diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java index 4dc3c1c0d..d26f9f646 100644 --- a/src/com/android/launcher3/qsb/QsbContainerView.java +++ b/src/com/android/launcher3/qsb/QsbContainerView.java @@ -39,12 +39,14 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.config.FeatureFlags; /** * A frame layout which contains a QSB. This internally uses fragment to bind the view, which * allows it to contain the logic for {@link Fragment#startActivityForResult(Intent, int)}. + * + * Note: AppWidgetManagerCompat can be disabled using FeatureFlags. In QSB, we should use + * AppWidgetManager directly, so that it keeps working in that case. */ public class QsbContainerView extends FrameLayout { @@ -106,7 +108,7 @@ public class QsbContainerView extends FrameLayout { return QsbWidgetHostView.getDefaultView(container); } - AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(activity); + AppWidgetManager widgetManager = AppWidgetManager.getInstance(activity); InvariantDeviceProfile idp = LauncherAppState.getIDP(activity); Bundle opts = new Bundle(); @@ -129,7 +131,8 @@ public class QsbContainerView extends FrameLayout { } widgetId = mQsbWidgetHost.allocateAppWidgetId(); - isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(widgetId, mWidgetInfo, opts); + isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed( + widgetId, mWidgetInfo.getProfile(), mWidgetInfo.provider, opts); if (!isWidgetBound) { mQsbWidgetHost.deleteAppWidgetId(widgetId); widgetId = -1; diff --git a/src/com/android/launcher3/touch/OverScroll.java b/src/com/android/launcher3/touch/OverScroll.java new file mode 100644 index 000000000..dc801ec4c --- /dev/null +++ b/src/com/android/launcher3/touch/OverScroll.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.touch; + +/** + * Utility methods for overscroll damping and related effect. + */ +public class OverScroll { + + private static final float OVERSCROLL_DAMP_FACTOR = 0.07f; + + /** + * This curve determines how the effect of scrolling over the limits of the page diminishes + * as the user pulls further and further from the bounds + * + * @param f The percentage of how much the user has overscrolled. + * @return A transformed percentage based on the influence curve. + */ + private static float overScrollInfluenceCurve(float f) { + f -= 1.0f; + return f * f * f + 1.0f; + } + + /** + * @param amount The original amount overscrolled. + * @param max The maximum amount that the View can overscroll. + * @return The dampened overscroll amount. + */ + public static int dampedScroll(float amount, int max) { + if (Float.compare(amount, 0) == 0) return 0; + + float f = amount / max; + f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f))); + + // Clamp this factor, f, to -1 < f < 1 + if (Math.abs(f) >= 1) { + f /= Math.abs(f); + } + + return Math.round(OVERSCROLL_DAMP_FACTOR * f * max); + } +} diff --git a/src/com/android/launcher3/allapps/VerticalPullDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java index 13c4f63f0..be4648eef 100644 --- a/src/com/android/launcher3/allapps/VerticalPullDetector.java +++ b/src/com/android/launcher3/touch/SwipeDetector.java @@ -1,32 +1,52 @@ -package com.android.launcher3.allapps; +/* + * 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.touch; +import static android.view.MotionEvent.INVALID_POINTER_ID; import android.content.Context; +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.view.animation.Interpolator; /** - * One dimensional scroll gesture detector for all apps container pull up interaction. - * Client (e.g., AllAppsTransitionController) of this class can register a listener. - * <p/> - * Features that this gesture detector can support. + * One dimensional scroll/drag/swipe gesture detector. + * + * Definition of swipe is different from android system in that this detector handles + * 'swipe to dismiss', 'swiping up/down a container' but also keeps scrolling state before + * swipe action happens */ -public class VerticalPullDetector { +public class SwipeDetector { private static final boolean DBG = false; - private static final String TAG = "VerticalPullDetector"; - - private final float mTouchSlop; + private static final String TAG = "SwipeDetector"; private int mScrollConditions; - public static final int DIRECTION_UP = 1 << 0; - public static final int DIRECTION_DOWN = 1 << 1; - public static final int DIRECTION_BOTH = DIRECTION_DOWN | DIRECTION_UP; + public static final int DIRECTION_POSITIVE = 1 << 0; + public static final int DIRECTION_NEGATIVE = 1 << 1; + public static final int DIRECTION_BOTH = DIRECTION_NEGATIVE | DIRECTION_POSITIVE; private static final float ANIMATION_DURATION = 1200; private static final float FAST_FLING_PX_MS = 10; + protected int mActivePointerId = INVALID_POINTER_ID; + /** * The minimum release velocity in pixels per millisecond that triggers fling.. */ @@ -47,6 +67,42 @@ public class VerticalPullDetector { SETTLING // onDragEnd } + public static abstract class Direction { + + abstract float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint); + + /** + * Distance in pixels a touch can wander before we think the user is scrolling. + */ + abstract float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos); + } + + public static final Direction VERTICAL = new Direction() { + + @Override + float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint) { + return ev.getY(pointerIndex) - refPoint.y; + } + + @Override + float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos) { + return Math.abs(ev.getX(pointerIndex) - downPos.x); + } + }; + + public static final Direction HORIZONTAL = new Direction() { + + @Override + float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint) { + return ev.getX(pointerIndex) - refPoint.x; + } + + @Override + float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos) { + return Math.abs(ev.getY(pointerIndex) - downPos.y); + } + }; + //------------------- ScrollState transition diagram ----------------------------------- // // IDLE -> (mDisplacement > mTouchSlop) -> DRAGGING @@ -93,27 +149,24 @@ public class VerticalPullDetector { return mState == ScrollState.DRAGGING; } - private float mDownX; - private float mDownY; + private final PointF mDownPos = new PointF(); + private final PointF mLastPos = new PointF(); + private final Direction mDir; + + private final float mTouchSlop; + + /* Client of this gesture detector can register a callback. */ + private final Listener mListener; - private float mLastY; private long mCurrentMillis; private float mVelocity; private float mLastDisplacement; - private float mDisplacementY; - private float mDisplacementX; + private float mDisplacement; private float mSubtractDisplacement; private boolean mIgnoreSlopWhenSettling; - /* Client of this gesture detector can register a callback. */ - private Listener mListener; - - public void setListener(Listener l) { - mListener = l; - } - public interface Listener { void onDragStart(boolean start); @@ -122,8 +175,15 @@ public class VerticalPullDetector { void onDragEnd(float velocity, boolean fling); } - public VerticalPullDetector(Context context) { - mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + public SwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) { + this(ViewConfiguration.get(context).getScaledTouchSlop(), l, dir); + } + + @VisibleForTesting + protected SwipeDetector(float touchSlope, @NonNull Listener l, @NonNull Direction dir) { + mTouchSlop = touchSlope; + mListener = l; + mDir = dir; } public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) { @@ -131,51 +191,65 @@ public class VerticalPullDetector { mIgnoreSlopWhenSettling = ignoreSlop; } - private boolean shouldScrollStart() { - // reject cases where the slop condition is not met. - if (Math.abs(mDisplacementY) < mTouchSlop) { + private boolean shouldScrollStart(MotionEvent ev, int pointerIndex) { + // reject cases where the angle or slop condition is not met. + if (Math.max(mDir.getActiveTouchSlop(ev, pointerIndex, mDownPos), mTouchSlop) + > Math.abs(mDisplacement)) { return false; } - // reject cases where the angle condition is not met. - float deltaY = Math.abs(mDisplacementY); - float deltaX = Math.max(Math.abs(mDisplacementX), 1); - if (deltaX > deltaY) { - return false; - } // Check if the client is interested in scroll in current direction. - if (((mScrollConditions & DIRECTION_DOWN) > 0 && mDisplacementY > 0) || - ((mScrollConditions & DIRECTION_UP) > 0 && mDisplacementY < 0)) { + if (((mScrollConditions & DIRECTION_NEGATIVE) > 0 && mDisplacement > 0) || + ((mScrollConditions & DIRECTION_POSITIVE) > 0 && mDisplacement < 0)) { return true; } return false; } public boolean onTouchEvent(MotionEvent ev) { - switch (ev.getAction()) { + switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: - mDownX = ev.getX(); - mDownY = ev.getY(); + mActivePointerId = ev.getPointerId(0); + mDownPos.set(ev.getX(), ev.getY()); + mLastPos.set(mDownPos); mLastDisplacement = 0; - mDisplacementY = 0; + mDisplacement = 0; mVelocity = 0; if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) { setState(ScrollState.DRAGGING); } break; + //case MotionEvent.ACTION_POINTER_DOWN: + case MotionEvent.ACTION_POINTER_UP: + int ptrIdx = ev.getActionIndex(); + int ptrId = ev.getPointerId(ptrIdx); + if (ptrId == mActivePointerId) { + final int newPointerIdx = ptrIdx == 0 ? 1 : 0; + mDownPos.set( + ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x), + ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y)); + mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx)); + mActivePointerId = ev.getPointerId(newPointerIdx); + } + break; case MotionEvent.ACTION_MOVE: - mDisplacementX = ev.getX() - mDownX; - mDisplacementY = ev.getY() - mDownY; - computeVelocity(ev); + int pointerIndex = ev.findPointerIndex(mActivePointerId); + if (pointerIndex == INVALID_POINTER_ID) { + break; + } + mDisplacement = mDir.getDisplacement(ev, pointerIndex, mDownPos); + computeVelocity(mDir.getDisplacement(ev, pointerIndex, mLastPos), + ev.getEventTime()); // handle state and listener calls. - if (mState != ScrollState.DRAGGING && shouldScrollStart()) { + if (mState != ScrollState.DRAGGING && shouldScrollStart(ev, pointerIndex)) { setState(ScrollState.DRAGGING); } if (mState == ScrollState.DRAGGING) { reportDragging(); } + mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex)); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: @@ -185,12 +259,8 @@ public class VerticalPullDetector { } break; default: - //TODO: add multi finger tracking by tracking active pointer. break; } - // Do house keeping. - mLastDisplacement = mDisplacementY; - mLastY = ev.getY(); return true; } @@ -210,7 +280,7 @@ public class VerticalPullDetector { if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) { mSubtractDisplacement = 0; } - if (mDisplacementY > 0) { + if (mDisplacement > 0) { mSubtractDisplacement = mTouchSlop; } else { mSubtractDisplacement = -mTouchSlop; @@ -218,14 +288,14 @@ public class VerticalPullDetector { } private boolean reportDragging() { - float delta = mDisplacementY - mLastDisplacement; - if (delta != 0) { + if (mDisplacement != mLastDisplacement) { if (DBG) { Log.d(TAG, String.format("onDrag disp=%.1f, velocity=%.1f", - mDisplacementY, mVelocity)); + mDisplacement, mVelocity)); } - return mListener.onDrag(mDisplacementY - mSubtractDisplacement, mVelocity); + mLastDisplacement = mDisplacement; + return mListener.onDrag(mDisplacement - mSubtractDisplacement, mVelocity); } return true; } @@ -233,19 +303,15 @@ public class VerticalPullDetector { private void reportDragEnd() { if (DBG) { Log.d(TAG, String.format("onScrollEnd disp=%.1f, velocity=%.1f", - mDisplacementY, mVelocity)); + mDisplacement, mVelocity)); } mListener.onDragEnd(mVelocity, Math.abs(mVelocity) > RELEASE_VELOCITY_PX_MS); } /** - * Computes the damped velocity using the two motion events and the previous velocity. + * Computes the damped velocity. */ - private float computeVelocity(MotionEvent to) { - return computeVelocity(to.getY() - mLastY, to.getEventTime()); - } - public float computeVelocity(float delta, long currentMillis) { long previousMillis = mCurrentMillis; mCurrentMillis = currentMillis; @@ -275,7 +341,7 @@ public class VerticalPullDetector { return (1.0f - alpha) * from + alpha * to; } - public long calculateDuration(float velocity, float progressNeeded) { + public static long calculateDuration(float velocity, float progressNeeded) { // TODO: make these values constants after tuning. float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity)); float travelDistance = Math.max(0.2f, progressNeeded); diff --git a/src/com/android/launcher3/util/SettingsObserver.java b/src/com/android/launcher3/util/SettingsObserver.java new file mode 100644 index 000000000..6baa24293 --- /dev/null +++ b/src/com/android/launcher3/util/SettingsObserver.java @@ -0,0 +1,100 @@ +/* + * 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.content.ContentResolver; +import android.database.ContentObserver; +import android.os.Handler; +import android.provider.Settings; + +public interface SettingsObserver { + + /** + * Registers the content observer to call {@link #onSettingChanged(boolean)} when any of the + * passed settings change. The value passed to onSettingChanged() is based on the key setting. + */ + void register(String keySetting, String ... dependentSettings); + void unregister(); + void onSettingChanged(boolean keySettingEnabled); + + + abstract class Secure extends ContentObserver implements SettingsObserver { + private ContentResolver mResolver; + private String mKeySetting; + + public Secure(ContentResolver resolver) { + super(new Handler()); + mResolver = resolver; + } + + @Override + public void register(String keySetting, String ... dependentSettings) { + mKeySetting = keySetting; + mResolver.registerContentObserver( + Settings.Secure.getUriFor(mKeySetting), false, this); + for (String setting : dependentSettings) { + mResolver.registerContentObserver( + Settings.Secure.getUriFor(setting), false, this); + } + onChange(true); + } + + @Override + public void unregister() { + mResolver.unregisterContentObserver(this); + } + + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + onSettingChanged(Settings.Secure.getInt(mResolver, mKeySetting, 1) == 1); + } + } + + abstract class System extends ContentObserver implements SettingsObserver { + private ContentResolver mResolver; + private String mKeySetting; + + public System(ContentResolver resolver) { + super(new Handler()); + mResolver = resolver; + } + + @Override + public void register(String keySetting, String ... dependentSettings) { + mKeySetting = keySetting; + mResolver.registerContentObserver( + Settings.System.getUriFor(mKeySetting), false, this); + for (String setting : dependentSettings) { + mResolver.registerContentObserver( + Settings.System.getUriFor(setting), false, this); + } + onChange(true); + } + + @Override + public void unregister() { + mResolver.unregisterContentObserver(this); + } + + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + onSettingChanged(Settings.System.getInt(mResolver, mKeySetting, 1) == 1); + } + } +} diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java index 4cb6ca831..e5c1dd1b4 100644 --- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java +++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java @@ -16,11 +16,13 @@ package com.android.launcher3.util; +import android.os.Process; import android.view.View; import android.view.View.OnAttachStateChangeListener; import android.view.ViewTreeObserver.OnDrawListener; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherModel; import java.util.ArrayList; import java.util.concurrent.Executor; @@ -37,6 +39,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, private Launcher mLauncher; private View mAttachedView; private boolean mCompleted; + private boolean mIsExecuting; private boolean mLoadAnimationCompleted; private boolean mFirstDrawCompleted; @@ -62,6 +65,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, @Override public void execute(Runnable command) { mTasks.add(command); + LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_BACKGROUND); } @Override @@ -78,6 +82,13 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, mAttachedView.post(this); } + /** + * Returns whether the executor is still queuing tasks and hasn't yet executed them. + */ + public boolean canQueue() { + return !mIsExecuting && !mCompleted; + } + public void onLoadAnimationCompleted() { mLoadAnimationCompleted = true; if (mAttachedView != null) { @@ -89,6 +100,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, public void run() { // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called. if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) { + mIsExecuting = true; for (final Runnable r : mTasks) { mExecutor.execute(r); } @@ -99,6 +111,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, public void markCompleted() { mTasks.clear(); mCompleted = true; + mIsExecuting = false; if (mAttachedView != null) { mAttachedView.getViewTreeObserver().removeOnDrawListener(this); mAttachedView.removeOnAttachStateChangeListener(this); @@ -106,5 +119,6 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, if (mLauncher != null) { mLauncher.clearPendingExecutor(this); } + LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_DEFAULT); } } diff --git a/src/com/android/launcher3/widget/WidgetAddFlowHandler.java b/src/com/android/launcher3/widget/WidgetAddFlowHandler.java index 629f30c26..5387be839 100644 --- a/src/com/android/launcher3/widget/WidgetAddFlowHandler.java +++ b/src/com/android/launcher3/widget/WidgetAddFlowHandler.java @@ -15,10 +15,8 @@ */ package com.android.launcher3.widget; -import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; -import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; @@ -26,7 +24,6 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.util.PendingRequestArgs; /** @@ -56,15 +53,8 @@ public class WidgetAddFlowHandler implements Parcelable { public void startBindFlow(Launcher launcher, int appWidgetId, ItemInfo info, int requestCode) { launcher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, this, info)); - - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mProviderInfo.provider); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, - mProviderInfo.getProfile()); - // TODO: we need to make sure that this accounts for the options bundle. - // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); - launcher.startActivityForResult(intent, requestCode); + launcher.getAppWidgetHost() + .startBindFlow(launcher, appWidgetId, mProviderInfo, requestCode); } /** @@ -85,9 +75,7 @@ public class WidgetAddFlowHandler implements Parcelable { return false; } launcher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, this, info)); - - AppWidgetManagerCompat.getInstance(launcher).startConfigActivity( - mProviderInfo, appWidgetId, launcher, launcher.getAppWidgetHost(), requestCode); + launcher.getAppWidgetHost().startConfigActivity(launcher, appWidgetId, requestCode); return true; } diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index 717a61c1c..01101ac74 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -40,7 +40,7 @@ import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.allapps.VerticalPullDetector; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; @@ -58,7 +58,7 @@ import java.util.List; * Bottom sheet for the "Widgets" system shortcut in the long-press popup. */ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettable, TouchController, - VerticalPullDetector.Listener, View.OnClickListener, View.OnLongClickListener, + SwipeDetector.Listener, View.OnClickListener, View.OnLongClickListener, DragController.DragListener { private int mTranslationYOpen; @@ -69,9 +69,9 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab private ItemInfo mOriginalItemInfo; private ObjectAnimator mOpenCloseAnimator; private Interpolator mFastOutSlowInInterpolator; - private VerticalPullDetector.ScrollInterpolator mScrollInterpolator; + private SwipeDetector.ScrollInterpolator mScrollInterpolator; private Rect mInsets; - private VerticalPullDetector mVerticalPullDetector; + private SwipeDetector mSwipeDetector; private GradientView mGradientBackground; public WidgetsBottomSheet(Context context, AttributeSet attrs) { @@ -85,10 +85,9 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab mOpenCloseAnimator = LauncherAnimUtils.ofPropertyValuesHolder(this); mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in); - mScrollInterpolator = new VerticalPullDetector.ScrollInterpolator(); + mScrollInterpolator = new SwipeDetector.ScrollInterpolator(); mInsets = new Rect(); - mVerticalPullDetector = new VerticalPullDetector(context); - mVerticalPullDetector.setListener(this); + mSwipeDetector = new SwipeDetector(context, this, SwipeDetector.VERTICAL); mGradientBackground = (GradientView) mLauncher.getLayoutInflater().inflate( R.layout.gradient_bg, mLauncher.getDragLayer(), false); } @@ -195,7 +194,7 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mVerticalPullDetector.finishedScrolling(); + mSwipeDetector.finishedScrolling(); } }); mOpenCloseAnimator.setInterpolator(mFastOutSlowInInterpolator); @@ -216,11 +215,11 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mVerticalPullDetector.finishedScrolling(); + mSwipeDetector.finishedScrolling(); onCloseComplete(); } }); - mOpenCloseAnimator.setInterpolator(mVerticalPullDetector.isIdleState() + mOpenCloseAnimator.setInterpolator(mSwipeDetector.isIdleState() ? mFastOutSlowInInterpolator : mScrollInterpolator); mOpenCloseAnimator.start(); } else { @@ -265,7 +264,7 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab getPaddingRight() + rightInset, getPaddingBottom() + bottomInset); } - /* VerticalPullDetector.Listener */ + /* SwipeDetector.Listener */ @Override public void onDragStart(boolean start) { @@ -291,12 +290,12 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab public void onDragEnd(float velocity, boolean fling) { if ((fling && velocity > 0) || getTranslationY() > (mTranslationYRange) / 2) { mScrollInterpolator.setVelocityAtZero(velocity); - mOpenCloseAnimator.setDuration(mVerticalPullDetector.calculateDuration(velocity, + mOpenCloseAnimator.setDuration(SwipeDetector.calculateDuration(velocity, (mTranslationYClosed - getTranslationY()) / mTranslationYRange)); close(true); } else { mIsOpen = false; - mOpenCloseAnimator.setDuration(mVerticalPullDetector.calculateDuration(velocity, + mOpenCloseAnimator.setDuration(SwipeDetector.calculateDuration(velocity, (getTranslationY() - mTranslationYOpen) / mTranslationYRange)); open(true); } @@ -304,17 +303,17 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab @Override public boolean onControllerTouchEvent(MotionEvent ev) { - return mVerticalPullDetector.onTouchEvent(ev); + return mSwipeDetector.onTouchEvent(ev); } @Override public boolean onControllerInterceptTouchEvent(MotionEvent ev) { - int directionsToDetectScroll = mVerticalPullDetector.isIdleState() ? - VerticalPullDetector.DIRECTION_DOWN : 0; - mVerticalPullDetector.setDetectableScrollConditions( + int directionsToDetectScroll = mSwipeDetector.isIdleState() ? + SwipeDetector.DIRECTION_NEGATIVE : 0; + mSwipeDetector.setDetectableScrollConditions( directionsToDetectScroll, false); - mVerticalPullDetector.onTouchEvent(ev); - return mVerticalPullDetector.isDraggingOrSettling(); + mSwipeDetector.onTouchEvent(ev); + return mSwipeDetector.isDraggingOrSettling(); } /* DragListener */ diff --git a/src_flags/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java index 42a110cfe..3ffb6c937 100644 --- a/src_flags/com/android/launcher3/config/FeatureFlags.java +++ b/src_flags/com/android/launcher3/config/FeatureFlags.java @@ -19,48 +19,7 @@ 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; +public final class FeatureFlags extends BaseFlags { private FeatureFlags() {} - - // Custom flags go below this - public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false; - public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false; - 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 = 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 = true; - // When enabled the promise icon is visible in all apps while installation an app. - public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false; - // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps - public static boolean LAUNCHER3_GRADIENT_ALL_APPS = true; - // When enabled allows use of physics based motions in the Launcher. - public static boolean LAUNCHER3_PHYSICS = true; - // When enabled allows use of spring motions on the icons. - public static boolean LAUNCHER3_SPRING_ICONS = true; - - // Feature flag to enable moving the QSB on the 0th screen of the workspace. - public static final boolean QSB_ON_FIRST_SCREEN = true; - // When enabled the all-apps icon is not added to the hotseat. - public static final boolean NO_ALL_APPS_ICON = true; - // When enabled fling down gesture on the first workspace triggers search. - public static final boolean PULLDOWN_SEARCH = false; - // When enabled the status bar may show dark icons based on the top of the wallpaper. - public static final boolean LIGHT_STATUS_BAR = false; - // When enabled 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 {@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/src/com/android/launcher3/InvariantDeviceProfileTest.java b/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java deleted file mode 100644 index 230d623e9..000000000 --- a/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java +++ /dev/null @@ -1,119 +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; - -import android.content.res.Resources; -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.Rect; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; - -import java.util.ArrayList; - -/** - * Tests the {@link DeviceProfile} and {@link InvariantDeviceProfile}. - */ -@SmallTest -public class InvariantDeviceProfileTest extends AndroidTestCase { - - private static final String TAG = "DeviceProfileTest"; - private static final boolean DEBUG = false; - - private InvariantDeviceProfile mInvariantProfile; - private ArrayList<InvariantDeviceProfile> mPredefinedDeviceProfiles; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mInvariantProfile = new InvariantDeviceProfile(getContext()); - mPredefinedDeviceProfiles = mInvariantProfile.getPredefinedDeviceProfiles(getContext()); - } - - @Override - protected void tearDown() throws Exception { - // Nothing to tear down as this class only tests static methods. - } - - public void testFindClosestDeviceProfile2() { - for (InvariantDeviceProfile idf: mPredefinedDeviceProfiles) { - ArrayList<InvariantDeviceProfile> predefinedProfilesCopy = - new ArrayList<>(mPredefinedDeviceProfiles); - ArrayList<InvariantDeviceProfile> closestProfiles = - mInvariantProfile.findClosestDeviceProfiles( - idf.minWidthDps, idf.minHeightDps, predefinedProfilesCopy - ); - assertTrue(closestProfiles.get(0).equals(idf)); - } - } - - /** - * Used to print out how the invDistWeightedInterpolate works between device profiles to - * tweak the two constants that control how the interpolation curve is shaped. - */ - public void testInvInterpolation() { - - InvariantDeviceProfile p1 = mPredefinedDeviceProfiles.get(7); // e.g., Large Phone - InvariantDeviceProfile p2 = mPredefinedDeviceProfiles.get(8); // e.g., Nexus 7 - - ArrayList<PointF> pts = createInterpolatedPoints( - new PointF(p1.minWidthDps, p1.minHeightDps), - new PointF(p2.minWidthDps, p2.minHeightDps), - 20f); - - for (int i = 0; i < pts.size(); i++) { - ArrayList<InvariantDeviceProfile> closestProfiles = - mInvariantProfile.findClosestDeviceProfiles( - pts.get(i).x, pts.get(i).y, mPredefinedDeviceProfiles); - InvariantDeviceProfile result = - mInvariantProfile.invDistWeightedInterpolate( - pts.get(i).x, pts.get(i).y, closestProfiles); - if (DEBUG) { - Log.d(TAG, String.format("width x height = (%f, %f)] iconSize = %f", - pts.get(i).x, pts.get(i).y, result.iconSize)); - } - } - } - - private ArrayList<PointF> createInterpolatedPoints(PointF a, PointF b, float numPts) { - ArrayList<PointF> result = new ArrayList<PointF>(); - result.add(a); - for (float i = 1; i < numPts; i = i + 1.0f) { - result.add(new PointF((b.x * i + a.x * (numPts - i)) / numPts, - (b.y * i + a.y * (numPts - i)) / numPts)); - } - result.add(b); - return result; - } - - /** - * Ensures that system calls (e.g., WindowManager, DisplayMetrics) that require contexts are - * properly working to generate minimum width and height of the display. - */ - public void test_hammerhead() { - if (!android.os.Build.DEVICE.equals("hammerhead")) { - return; - } - assertEquals(4, mInvariantProfile.numRows); - assertEquals(4, mInvariantProfile.numColumns); - assertEquals(5, mInvariantProfile.numHotseatIcons); - } - - // Add more tests for other devices, however, running them once on a single device is enough - // for verifying that for a platform version, the WindowManager and DisplayMetrics is - // working as intended. -} diff --git a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java index 26ec69b1c..846a16370 100644 --- a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java +++ b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java @@ -16,85 +16,78 @@ package com.android.launcher3.allapps.search; import android.content.ComponentName; -import android.test.InstrumentationTestCase; +import android.support.test.runner.AndroidJUnit4; import com.android.launcher3.AppInfo; import com.android.launcher3.Utilities; -import java.util.ArrayList; -import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; /** * Unit tests for {@link DefaultAppSearchAlgorithm} */ -public class DefaultAppSearchAlgorithmTest extends InstrumentationTestCase { - - private List<AppInfo> mAppsList; - private DefaultAppSearchAlgorithm mAlgorithm; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mAppsList = new ArrayList<>(); - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - mAlgorithm = new DefaultAppSearchAlgorithm(mAppsList); - } - }); - } +@RunWith(AndroidJUnit4.class) +public class DefaultAppSearchAlgorithmTest { + private static final DefaultAppSearchAlgorithm.StringMatcher MATCHER = + DefaultAppSearchAlgorithm.StringMatcher.getInstance(); + @Test public void testMatches() { - assertTrue(mAlgorithm.matches(getInfo("white cow"), "cow")); - assertTrue(mAlgorithm.matches(getInfo("whiteCow"), "cow")); - assertTrue(mAlgorithm.matches(getInfo("whiteCOW"), "cow")); - assertTrue(mAlgorithm.matches(getInfo("whitecowCOW"), "cow")); - assertTrue(mAlgorithm.matches(getInfo("white2cow"), "cow")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("white cow"), "cow", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whiteCow"), "cow", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whiteCOW"), "cow", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whitecowCOW"), "cow", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("white2cow"), "cow", MATCHER)); - assertFalse(mAlgorithm.matches(getInfo("whitecow"), "cow")); - assertFalse(mAlgorithm.matches(getInfo("whitEcow"), "cow")); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whitecow"), "cow", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whitEcow"), "cow", MATCHER)); - assertTrue(mAlgorithm.matches(getInfo("whitecowCow"), "cow")); - assertTrue(mAlgorithm.matches(getInfo("whitecow cow"), "cow")); - assertFalse(mAlgorithm.matches(getInfo("whitecowcow"), "cow")); - assertFalse(mAlgorithm.matches(getInfo("whit ecowcow"), "cow")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whitecowCow"), "cow", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whitecow cow"), "cow", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whitecowcow"), "cow", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whit ecowcow"), "cow", MATCHER)); - assertTrue(mAlgorithm.matches(getInfo("cats&dogs"), "dog")); - assertTrue(mAlgorithm.matches(getInfo("cats&Dogs"), "dog")); - assertTrue(mAlgorithm.matches(getInfo("cats&Dogs"), "&")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("cats&dogs"), "dog", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("cats&Dogs"), "dog", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("cats&Dogs"), "&", MATCHER)); - assertTrue(mAlgorithm.matches(getInfo("2+43"), "43")); - assertFalse(mAlgorithm.matches(getInfo("2+43"), "3")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("2+43"), "43", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("2+43"), "3", MATCHER)); - assertTrue(mAlgorithm.matches(getInfo("Q"), "q")); - assertTrue(mAlgorithm.matches(getInfo(" Q"), "q")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("Q"), "q", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo(" Q"), "q", MATCHER)); // match lower case words - assertTrue(mAlgorithm.matches(getInfo("elephant"), "e")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("elephant"), "e", MATCHER)); - assertTrue(mAlgorithm.matches(getInfo("电子邮件"), "电")); - assertTrue(mAlgorithm.matches(getInfo("电子邮件"), "电子")); - assertFalse(mAlgorithm.matches(getInfo("电子邮件"), "子")); - assertFalse(mAlgorithm.matches(getInfo("电子邮件"), "邮件")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "电", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "电子", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "子", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "邮件", MATCHER)); - assertFalse(mAlgorithm.matches(getInfo("Bot"), "ba")); - assertFalse(mAlgorithm.matches(getInfo("bot"), "ba")); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("Bot"), "ba", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("bot"), "ba", MATCHER)); } + @Test public void testMatchesVN() { if (!Utilities.ATLEAST_NOUGAT) { return; } - assertTrue(mAlgorithm.matches(getInfo("다운로드"), "다")); - assertTrue(mAlgorithm.matches(getInfo("드라이브"), "드")); - assertTrue(mAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷ")); - assertTrue(mAlgorithm.matches(getInfo("운로 드라이브"), "ㄷ")); - assertTrue(mAlgorithm.matches(getInfo("abc"), "åbç")); - assertTrue(mAlgorithm.matches(getInfo("Alpha"), "ål")); - - assertFalse(mAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷㄷ")); - assertFalse(mAlgorithm.matches(getInfo("로드라이브"), "ㄷ")); - assertFalse(mAlgorithm.matches(getInfo("abc"), "åç")); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("다운로드"), "다", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("드라이브"), "드", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷ", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("운로 드라이브"), "ㄷ", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("abc"), "åbç", MATCHER)); + assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("Alpha"), "ål", MATCHER)); + + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷㄷ", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("로드라이브"), "ㄷ", MATCHER)); + assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("abc"), "åç", MATCHER)); } private AppInfo getInfo(String title) { diff --git a/tests/src/com/android/launcher3/logging/FileLogTest.java b/tests/src/com/android/launcher3/logging/FileLogTest.java index c24cc3fb7..7048c2868 100644 --- a/tests/src/com/android/launcher3/logging/FileLogTest.java +++ b/tests/src/com/android/launcher3/logging/FileLogTest.java @@ -37,6 +37,9 @@ public class FileLogTest extends AndroidTestCase { } public void testPrintLog() throws Exception { + if (!FileLog.ENABLED) { + return; + } FileLog.print("Testing", "hoolalala"); StringWriter writer = new StringWriter(); FileLog.flushAll(new PrintWriter(writer)); @@ -54,6 +57,9 @@ public class FileLogTest extends AndroidTestCase { } public void testOldFileTruncated() throws Exception { + if (!FileLog.ENABLED) { + return; + } FileLog.print("Testing", "hoolalala"); StringWriter writer = new StringWriter(); FileLog.flushAll(new PrintWriter(writer)); diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java index 4c80902f0..ae15f086f 100644 --- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java +++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java @@ -20,9 +20,9 @@ import com.android.launcher3.util.Provider; import org.mockito.ArgumentCaptor; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -131,7 +131,7 @@ public class AddWorkspaceItemsTaskTest extends BaseModelUpdateTaskTestCase { // only info2 should be added because info was already added to the workspace // in setupWorkspaceWithHoles() verify(callbacks).bindAppsAdded(any(ArrayList.class), notAnimated.capture(), - animated.capture(), any(ArrayList.class)); + animated.capture(), isNull(ArrayList.class)); assertTrue(notAnimated.getValue().isEmpty()); assertEquals(1, animated.getValue().size()); diff --git a/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java b/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java new file mode 100644 index 000000000..80d6341e7 --- /dev/null +++ b/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java @@ -0,0 +1,275 @@ +/* + * 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.testcomponent; + +import android.graphics.Point; +import android.util.Pair; +import android.view.InputDevice; +import android.view.MotionEvent; +import android.view.MotionEvent.PointerCoords; +import android.view.MotionEvent.PointerProperties; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class to generate MotionEvent event sequences for testing touch gesture detectors. + */ +public class TouchEventGenerator { + + /** + * Amount of time between two generated events. + */ + private static final long TIME_INCREMENT_MS = 20L; + + /** + * Id of the fake device generating the events. + */ + private static final int DEVICE_ID = 2104; + + /** + * The fingers currently present on the emulated touch screen. + */ + private Map<Integer, Point> mFingers; + + /** + * Initial event time for the current sequence. + */ + private long mInitialTime; + + /** + * Time of the last generated event. + */ + private long mLastEventTime; + + /** + * Time of the next event. + */ + private long mTime; + + /** + * Receives the generated events. + */ + public interface Listener { + + /** + * Called when an event was generated. + */ + void onTouchEvent(MotionEvent event); + } + private final Listener mListener; + + public TouchEventGenerator(Listener listener) { + mListener = listener; + mFingers = new HashMap<Integer, Point>(); + } + + /** + * Adds a finger on the touchscreen. + */ + public TouchEventGenerator put(int id, int x, int y, long ms) { + checkFingerExistence(id, false); + boolean isInitialDown = mFingers.isEmpty(); + mFingers.put(id, new Point(x, y)); + int action; + if (isInitialDown) { + action = MotionEvent.ACTION_DOWN; + } else { + action = MotionEvent.ACTION_POINTER_DOWN; + // Set the id of the changed pointer. + action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT; + } + generateEvent(action, ms); + return this; + } + + /** + * Adds a finger on the touchscreen after advancing default time interval. + */ + public TouchEventGenerator put(int id, int x, int y) { + return put(id, x, y, TIME_INCREMENT_MS); + } + + /** + * Adjusts the position of a finger for an upcoming move event. + * + * @see #move(long ms) + */ + public TouchEventGenerator position(int id, int x, int y) { + checkFingerExistence(id, true); + mFingers.get(id).set(x, y); + return this; + } + + /** + * Commits the finger position changes of {@link #position(int, int, int)} by generating a move + * event. + * + * @see #position(int, int, int) + */ + public TouchEventGenerator move(long ms) { + generateEvent(MotionEvent.ACTION_MOVE, ms); + return this; + } + + /** + * Commits the finger position changes of {@link #position(int, int, int)} by generating a move + * event after advancing the default time interval. + * + * @see #position(int, int, int) + */ + public TouchEventGenerator move() { + return move(TIME_INCREMENT_MS); + } + + /** + * Moves a single finger on the touchscreen. + */ + public TouchEventGenerator move(int id, int x, int y, long ms) { + return position(id, x, y).move(ms); + } + + /** + * Moves a single finger on the touchscreen after advancing default time interval. + */ + public TouchEventGenerator move(int id, int x, int y) { + return move(id, x, y, TIME_INCREMENT_MS); + } + + /** + * Removes an existing finger from the touchscreen. + */ + public TouchEventGenerator lift(int id, long ms) { + checkFingerExistence(id, true); + boolean isFinalUp = mFingers.size() == 1; + int action; + if (isFinalUp) { + action = MotionEvent.ACTION_UP; + } else { + action = MotionEvent.ACTION_POINTER_UP; + // Set the id of the changed pointer. + action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT; + } + generateEvent(action, ms); + mFingers.remove(id); + return this; + } + + /** + * Removes a finger from the touchscreen. + */ + public TouchEventGenerator lift(int id, int x, int y, long ms) { + checkFingerExistence(id, true); + mFingers.get(id).set(x, y); + return lift(id, ms); + } + + /** + * Removes an existing finger from the touchscreen after advancing default time interval. + */ + public TouchEventGenerator lift(int id) { + return lift(id, TIME_INCREMENT_MS); + } + + /** + * Cancels an ongoing sequence. + */ + public TouchEventGenerator cancel(long ms) { + generateEvent(MotionEvent.ACTION_CANCEL, ms); + mFingers.clear(); + return this; + } + + /** + * Cancels an ongoing sequence. + */ + public TouchEventGenerator cancel() { + return cancel(TIME_INCREMENT_MS); + } + + private void checkFingerExistence(int id, boolean shouldExist) { + if (shouldExist != mFingers.containsKey(id)) { + throw new IllegalArgumentException( + shouldExist ? "Finger does not exist" : "Finger already exists"); + } + } + + private void generateEvent(int action, long ms) { + mTime = mLastEventTime + ms; + Pair<PointerProperties[], PointerCoords[]> state = getFingerState(); + MotionEvent event = MotionEvent.obtain( + mInitialTime, + mTime, + action, + state.first.length, + state.first, + state.second, + 0 /* metaState */, + 0 /* buttonState */, + 1.0f /* xPrecision */, + 1.0f /* yPrecision */, + DEVICE_ID, + 0 /* edgeFlags */, + InputDevice.SOURCE_TOUCHSCREEN, + 0 /* flags */); + mListener.onTouchEvent(event); + if (action == MotionEvent.ACTION_UP) { + resetTime(); + } + event.recycle(); + mLastEventTime = mTime; + } + + /** + * Returns the description of the fingers' state expected by MotionEvent. + */ + private Pair<PointerProperties[], PointerCoords[]> getFingerState() { + int nFingers = mFingers.size(); + PointerProperties[] properties = new PointerProperties[nFingers]; + PointerCoords[] coordinates = new PointerCoords[nFingers]; + + int index = 0; + for (Map.Entry<Integer, Point> entry : mFingers.entrySet()) { + int id = entry.getKey(); + Point location = entry.getValue(); + + PointerProperties property = new PointerProperties(); + property.id = id; + property.toolType = MotionEvent.TOOL_TYPE_FINGER; + properties[index] = property; + + PointerCoords coordinate = new PointerCoords(); + coordinate.x = location.x; + coordinate.y = location.y; + coordinate.pressure = 1.0f; + coordinates[index] = coordinate; + + index++; + } + + return new Pair<MotionEvent.PointerProperties[], MotionEvent.PointerCoords[]>( + properties, coordinates); + } + + /** + * Resets the time references for a new sequence. + */ + private void resetTime() { + mInitialTime = 0L; + mLastEventTime = -1L; + mTime = 0L; + } +} diff --git a/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java new file mode 100644 index 000000000..ff83131d1 --- /dev/null +++ b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java @@ -0,0 +1,115 @@ +/* + * 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.touch; + +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; +import android.view.MotionEvent; +import android.view.ViewConfiguration; + +import com.android.launcher3.testcomponent.TouchEventGenerator; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyFloat; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class SwipeDetectorTest { + + private static final String TAG = SwipeDetectorTest.class.getSimpleName(); + public static void L(String s, Object... parts) { + Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts)); + } + + private TouchEventGenerator mGenerator; + private SwipeDetector mDetector; + private int mTouchSlop; + + @Mock + private SwipeDetector.Listener mMockListener; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mGenerator = new TouchEventGenerator(new TouchEventGenerator.Listener() { + @Override + public void onTouchEvent(MotionEvent event) { + mDetector.onTouchEvent(event); + } + }); + + mDetector = new SwipeDetector(mTouchSlop, mMockListener, SwipeDetector.VERTICAL); + mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false); + mTouchSlop = ViewConfiguration.get(InstrumentationRegistry.getTargetContext()) + .getScaledTouchSlop(); + L("mTouchSlop=", mTouchSlop); + } + + @Test + public void testDragStart_vertical() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100, 100 + mTouchSlop); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDragStart(anyBoolean()); + } + + @Test + public void testDragStart_failed() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100 + mTouchSlop, 100); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener, never()).onDragStart(anyBoolean()); + } + + @Test + public void testDragStart_horizontal() throws Exception { + mDetector = new SwipeDetector(mTouchSlop, mMockListener, SwipeDetector.HORIZONTAL); + mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false); + + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100 + mTouchSlop, 100); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDragStart(anyBoolean()); + } + + @Test + public void testDrag() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100, 100 + mTouchSlop); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDrag(anyFloat(), anyFloat()); + } + + @Test + public void testDragEnd() throws Exception { + mGenerator.put(0, 100, 100); + mGenerator.move(0, 100, 100 + mTouchSlop); + mGenerator.move(0, 100, 100 + mTouchSlop * 2); + mGenerator.lift(0); + // TODO: actually calculate the following parameters and do exact value checks. + verify(mMockListener).onDragEnd(anyFloat(), anyBoolean()); + } +} diff --git a/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 47b43f530..7fb5d8521 100644 --- a/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -15,29 +15,26 @@ */ package com.android.launcher3.ui; +import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; +import android.content.pm.LauncherActivityInfo; import android.graphics.Point; -import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; +import android.support.test.InstrumentationRegistry; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.Direction; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; -import android.test.InstrumentationTestCase; import android.view.MotionEvent; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.LauncherSettings; @@ -45,25 +42,26 @@ import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.compat.AppWidgetManagerCompat; +import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.testcomponent.AppWidgetNoConfig; import com.android.launcher3.testcomponent.AppWidgetWithConfig; import com.android.launcher3.util.ManagedProfileHeuristic; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; +import org.junit.Before; + import java.util.Locale; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + /** * Base class for all instrumentation tests providing various utility methods. */ -public class LauncherInstrumentationTestCase extends InstrumentationTestCase { +public abstract class AbstractLauncherUiTest { public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10); public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 5; @@ -71,16 +69,15 @@ public class LauncherInstrumentationTestCase extends InstrumentationTestCase { public static final long DEFAULT_UI_TIMEOUT = 3000; public static final long DEFAULT_WORKER_TIMEOUT_SECS = 5; + protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); protected UiDevice mDevice; protected Context mTargetContext; protected String mTargetPackage; - @Override - protected void setUp() throws Exception { - super.setUp(); - + @Before + public void setUp() throws Exception { mDevice = UiDevice.getInstance(getInstrumentation()); - mTargetContext = getInstrumentation().getTargetContext(); + mTargetContext = InstrumentationRegistry.getTargetContext(); mTargetPackage = mTargetContext.getPackageName(); } @@ -97,56 +94,15 @@ public class LauncherInstrumentationTestCase extends InstrumentationTestCase { } } - /** - * Starts the launcher activity in the target package and returns the Launcher instance. - */ - protected Launcher startLauncher() { - return (Launcher) getInstrumentation().startActivitySync(getHomeIntent()); - } - - protected Intent getHomeIntent() { - return new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_HOME) - .setPackage(mTargetPackage) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - } - - /** - * Grants the launcher permission to bind widgets. - */ - protected void grantWidgetPermission() throws IOException { - // Check bind widget permission - if (mTargetContext.getPackageManager().checkPermission( - mTargetPackage, android.Manifest.permission.BIND_APPWIDGET) - != PackageManager.PERMISSION_GRANTED) { - runShellCommand("appwidget grantbind --package " + mTargetPackage); - } - } - - /** - * Sets the target launcher as default launcher. - */ - protected void setDefaultLauncher() throws IOException { - ActivityInfo launcher = mTargetContext.getPackageManager() - .queryIntentActivities(getHomeIntent(), 0).get(0).activityInfo; - runShellCommand("cmd package set-home-activity " + - new ComponentName(launcher.packageName, launcher.name).flattenToString()); - } - - protected void runShellCommand(String command) throws IOException { - ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation() - .executeShellCommand(command); - - // Read the input stream fully. - FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); - while (fis.read() != -1); - fis.close(); + protected Instrumentation getInstrumentation() { + return InstrumentationRegistry.getInstrumentation(); } /** * Opens all apps and returns the recycler view */ protected UiObject2 openAllApps() { + mDevice.waitForIdle(); if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { // clicking on the page indicator brings up all apps tray on non tablets. findViewById(R.id.page_indicator).click(); @@ -262,7 +218,7 @@ public class LauncherInstrumentationTestCase extends InstrumentationTestCase { protected void resetLoaderState() { try { - runTestOnUiThread(new Runnable() { + mMainThreadExecutor.execute(new Runnable() { @Override public void run() { ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext); @@ -279,7 +235,7 @@ public class LauncherInstrumentationTestCase extends InstrumentationTestCase { */ protected <T> T getOnUiThread(final Callable<T> callback) { try { - return new MainThreadExecutor().submit(callback).get(); + return mMainThreadExecutor.submit(callback).get(); } catch (Exception e) { throw new RuntimeException(e); } @@ -315,6 +271,10 @@ public class LauncherInstrumentationTestCase extends InstrumentationTestCase { return By.res(mTargetPackage, name); } + protected LauncherActivityInfo getSettingsApp() { + return LauncherAppsCompat.getInstance(mTargetContext) + .getActivityList("com.android.settings", Process.myUserHandle()).get(0); + } /** * Broadcast receiver which blocks until the result is received. diff --git a/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java b/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java index 0ced7cf33..46343a389 100644 --- a/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java +++ b/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java @@ -1,52 +1,55 @@ package com.android.launcher3.ui; import android.content.pm.LauncherActivityInfo; -import android.os.Process; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; -import android.test.suitebuilder.annotation.LargeTest; -import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertTrue; /** * Test for verifying apps is launched from all-apps */ @LargeTest -public class AllAppsAppLaunchTest extends LauncherInstrumentationTestCase { - - private LauncherActivityInfo mSettingsApp; +@RunWith(AndroidJUnit4.class) +public class AllAppsAppLaunchTest extends AbstractLauncherUiTest { - @Override - protected void setUp() throws Exception { - super.setUp(); - - mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext) - .getActivityList("com.android.settings", Process.myUserHandle()).get(0); - } + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Test public void testAppLauncher_portrait() throws Exception { lockRotation(true); performTest(); } + @Test public void testAppLauncher_landscape() throws Exception { lockRotation(false); performTest(); } private void performTest() throws Exception { - startLauncher(); + mActivityMonitor.startLauncher(); + + LauncherActivityInfo settingsApp = getSettingsApp(); // Open all apps and wait for load complete final UiObject2 appsContainer = openAllApps(); assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT)); // Open settings app and verify app launched - scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString())).click(); + scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString())).click(); assertTrue(mDevice.wait(Until.hasObject(By.pkg( - mSettingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT)); + settingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT)); } } diff --git a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java index 936175087..00f30ada9 100644 --- a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java +++ b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java @@ -1,58 +1,62 @@ package com.android.launcher3.ui; import android.content.pm.LauncherActivityInfo; -import android.os.Process; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; -import android.test.suitebuilder.annotation.LargeTest; -import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertTrue; /** * Test for dragging an icon from all-apps to homescreen. */ @LargeTest -public class AllAppsIconToHomeTest extends LauncherInstrumentationTestCase { - - private LauncherActivityInfo mSettingsApp; +@RunWith(AndroidJUnit4.class) +public class AllAppsIconToHomeTest extends AbstractLauncherUiTest { - @Override - protected void setUp() throws Exception { - super.setUp(); - setDefaultLauncher(); - - mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext) - .getActivityList("com.android.settings", Process.myUserHandle()).get(0); - } + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher(); + @Test public void testDragIcon_portrait() throws Throwable { lockRotation(true); performTest(); } + @Test public void testDragIcon_landscape() throws Throwable { lockRotation(false); performTest(); } private void performTest() throws Throwable { + LauncherActivityInfo settingsApp = getSettingsApp(); + clearHomescreen(); - startLauncher(); + mActivityMonitor.startLauncher(); // Open all apps and wait for load complete. final UiObject2 appsContainer = openAllApps(); assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT)); // Drag icon to homescreen. - UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString())); + UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString())); dragToWorkspace(icon, true); // Verify that the icon works on homescreen. - mDevice.findObject(By.text(mSettingsApp.getLabel().toString())).click(); + mDevice.findObject(By.text(settingsApp.getLabel().toString())).click(); assertTrue(mDevice.wait(Until.hasObject(By.pkg( - mSettingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT)); + settingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT)); } } diff --git a/tests/src/com/android/launcher3/ui/RotationPreferenceTest.java b/tests/src/com/android/launcher3/ui/RotationPreferenceTest.java deleted file mode 100644 index e84ad047f..000000000 --- a/tests/src/com/android/launcher3/ui/RotationPreferenceTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.android.launcher3.ui; - -import android.content.SharedPreferences; -import android.graphics.Rect; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject; -import android.support.test.uiautomator.UiSelector; -import android.test.suitebuilder.annotation.MediumTest; - -import com.android.launcher3.R; -import com.android.launcher3.Utilities; - -/** - * Test for auto rotate preference. - */ -@MediumTest -public class RotationPreferenceTest extends LauncherInstrumentationTestCase { - - private SharedPreferences mPrefs; - private boolean mOriginalRotationValue; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mDevice = UiDevice.getInstance(getInstrumentation()); - mTargetContext = getInstrumentation().getTargetContext(); - mTargetPackage = mTargetContext.getPackageName(); - mPrefs = Utilities.getPrefs(mTargetContext); - mOriginalRotationValue = mPrefs.getBoolean(Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false); - } - - @Override - protected void tearDown() throws Exception { - setRotationEnabled(mOriginalRotationValue); - super.tearDown(); - } - - public void testRotation_disabled() throws Exception { - if (mTargetContext.getResources().getBoolean(R.bool.allow_rotation)) { - // This is a tablet. The test is only valid to mobile devices. - return; - } - - setRotationEnabled(false); - mDevice.setOrientationRight(); - startLauncher(); - - Rect hotseat = getHotseatBounds(); - assertTrue(hotseat.width() > hotseat.height()); - } - - public void testRotation_enabled() throws Exception { - if (mTargetContext.getResources().getBoolean(R.bool.allow_rotation)) { - // This is a tablet. The test is only valid to mobile devices. - return; - } - - setRotationEnabled(true); - mDevice.setOrientationRight(); - startLauncher(); - - Rect hotseat = getHotseatBounds(); - assertTrue(hotseat.width() < hotseat.height()); - } - - private void setRotationEnabled(boolean enabled) { - mPrefs.edit().putBoolean(Utilities.ALLOW_ROTATION_PREFERENCE_KEY, enabled).commit(); - } - - private Rect getHotseatBounds() throws Exception { - UiObject hotseat = mDevice.findObject( - new UiSelector().resourceId(mTargetPackage + ":id/hotseat")); - hotseat.waitForExists(6000); - return hotseat.getVisibleBounds(); - } -} diff --git a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java index 3a0b6132c..a40ad7fad 100644 --- a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java +++ b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java @@ -2,54 +2,58 @@ package com.android.launcher3.ui; import android.content.pm.LauncherActivityInfo; import android.graphics.Point; -import android.os.Process; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; -import android.test.suitebuilder.annotation.LargeTest; import android.view.MotionEvent; import com.android.launcher3.R; -import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * Test for verifying that shortcuts are shown and can be launched after long pressing an app */ @LargeTest -public class ShortcutsLaunchTest extends LauncherInstrumentationTestCase { - - private LauncherActivityInfo mSettingsApp; +@RunWith(AndroidJUnit4.class) +public class ShortcutsLaunchTest extends AbstractLauncherUiTest { - @Override - protected void setUp() throws Exception { - super.setUp(); - setDefaultLauncher(); - - mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext) - .getActivityList("com.android.settings", Process.myUserHandle()).get(0); - } + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher(); + @Test public void testAppLauncher_portrait() throws Exception { lockRotation(true); performTest(); } + @Test public void testAppLauncher_landscape() throws Exception { lockRotation(false); performTest(); } private void performTest() throws Exception { - startLauncher(); + mActivityMonitor.startLauncher(); + LauncherActivityInfo settingsApp = getSettingsApp(); // Open all apps and wait for load complete final UiObject2 appsContainer = openAllApps(); assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT)); // Find settings app and verify shortcuts appear when long pressed - UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString())); + UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString())); // Press icon center until shortcuts appear Point iconCenter = icon.getVisibleCenter(); sendPointer(MotionEvent.ACTION_DOWN, iconCenter); @@ -63,7 +67,7 @@ public class ShortcutsLaunchTest extends LauncherInstrumentationTestCase { .findObject(getSelectorForId(R.id.bubble_text)); shortcut.click(); assertTrue(mDevice.wait(Until.hasObject(By.pkg( - mSettingsApp.getComponentName().getPackageName()) + settingsApp.getComponentName().getPackageName()) .text(shortcut.getText())), DEFAULT_UI_TIMEOUT)); } } diff --git a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java index 5d86d1ec6..434311dd6 100644 --- a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java +++ b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java @@ -2,40 +2,43 @@ package com.android.launcher3.ui; import android.content.pm.LauncherActivityInfo; import android.graphics.Point; -import android.os.Process; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; -import android.test.suitebuilder.annotation.LargeTest; import android.view.MotionEvent; import com.android.launcher3.R; -import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * Test for dragging a deep shortcut to the home screen. */ @LargeTest -public class ShortcutsToHomeTest extends LauncherInstrumentationTestCase { - - private LauncherActivityInfo mSettingsApp; +@RunWith(AndroidJUnit4.class) +public class ShortcutsToHomeTest extends AbstractLauncherUiTest { - @Override - protected void setUp() throws Exception { - super.setUp(); - setDefaultLauncher(); - - mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext) - .getActivityList("com.android.settings", Process.myUserHandle()).get(0); - } + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher(); + @Test public void testDragIcon_portrait() throws Throwable { lockRotation(true); performTest(); } + @Test public void testDragIcon_landscape() throws Throwable { lockRotation(false); performTest(); @@ -43,14 +46,16 @@ public class ShortcutsToHomeTest extends LauncherInstrumentationTestCase { private void performTest() throws Throwable { clearHomescreen(); - startLauncher(); + mActivityMonitor.startLauncher(); + + LauncherActivityInfo settingsApp = getSettingsApp(); // Open all apps and wait for load complete. final UiObject2 appsContainer = openAllApps(); assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT)); // Find the app and long press it to show shortcuts. - UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString())); + UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString())); // Press icon center until shortcuts appear Point iconCenter = icon.getVisibleCenter(); sendPointer(MotionEvent.ACTION_DOWN, iconCenter); @@ -69,7 +74,7 @@ public class ShortcutsToHomeTest extends LauncherInstrumentationTestCase { // (the app opens and has the same text as the shortcut). mDevice.findObject(By.text(shortcutName)).click(); assertTrue(mDevice.wait(Until.hasObject(By.pkg( - mSettingsApp.getComponentName().getPackageName()) + settingsApp.getComponentName().getPackageName()) .text(shortcutName)), DEFAULT_UI_TIMEOUT)); } } diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java index 0b4e34f94..a5c2e69af 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java @@ -15,75 +15,75 @@ */ package com.android.launcher3.ui.widget; -import android.app.Activity; -import android.app.Application; import android.appwidget.AppWidgetManager; import android.content.Intent; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; -import android.test.suitebuilder.annotation.LargeTest; import android.view.View; import com.android.launcher3.ItemInfo; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Workspace; import com.android.launcher3.testcomponent.WidgetConfigActivity; -import com.android.launcher3.ui.LauncherInstrumentationTestCase; +import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.util.Condition; -import com.android.launcher3.util.SimpleActivityMonitor; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.WidgetCell; -import java.util.concurrent.Callable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; /** * Test to verify widget configuration is properly shown. */ @LargeTest -public class AddConfigWidgetTest extends LauncherInstrumentationTestCase { +@RunWith(AndroidJUnit4.class) +public class AddConfigWidgetTest extends AbstractLauncherUiTest { + + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind(); private LauncherAppWidgetProviderInfo mWidgetInfo; - private SimpleActivityMonitor mActivityMonitor; - private MainThreadExecutor mMainThreadExecutor; private AppWidgetManager mAppWidgetManager; private int mWidgetId; @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { super.setUp(); mWidgetInfo = findWidgetProvider(true /* hasConfigureScreen */); - mActivityMonitor = new SimpleActivityMonitor(); - ((Application) getInstrumentation().getTargetContext().getApplicationContext()) - .registerActivityLifecycleCallbacks(mActivityMonitor); - mMainThreadExecutor = new MainThreadExecutor(); mAppWidgetManager = AppWidgetManager.getInstance(mTargetContext); - - grantWidgetPermission(); - } - - @Override - protected void tearDown() throws Exception { - ((Application) getInstrumentation().getTargetContext().getApplicationContext()) - .unregisterActivityLifecycleCallbacks(mActivityMonitor); - super.tearDown(); } + @Test public void testWidgetConfig() throws Throwable { runTest(false, true); } + @Test public void testWidgetConfig_rotate() throws Throwable { runTest(true, true); } + @Test public void testConfigCancelled() throws Throwable { runTest(false, false); } + @Test public void testConfigCancelled_rotate() throws Throwable { runTest(true, false); } @@ -96,7 +96,7 @@ public class AddConfigWidgetTest extends LauncherInstrumentationTestCase { lockRotation(true); clearHomescreen(); - startLauncher(); + mActivityMonitor.startLauncher(); // Open widget tray and wait for load complete. final UiObject2 widgetContainer = openWidgetsTray(); @@ -146,11 +146,11 @@ public class AddConfigWidgetTest extends LauncherInstrumentationTestCase { * Condition for searching widget id */ private class WidgetSearchCondition extends Condition - implements Callable<Boolean>, Workspace.ItemOperator { + implements Workspace.ItemOperator { @Override public boolean isTrue() throws Throwable { - return mMainThreadExecutor.submit(this).get(); + return mMainThreadExecutor.submit(mActivityMonitor.itemExists(this)).get(); } @Override @@ -159,21 +159,6 @@ public class AddConfigWidgetTest extends LauncherInstrumentationTestCase { ((LauncherAppWidgetInfo) info).providerName.equals(mWidgetInfo.provider) && ((LauncherAppWidgetInfo) info).appWidgetId == mWidgetId; } - - @Override - public Boolean call() throws Exception { - // Find the resumed launcher - Launcher launcher = null; - for (Activity a : mActivityMonitor.resumed) { - if (a instanceof Launcher) { - launcher = (Launcher) a; - } - } - if (launcher == null) { - return false; - } - return launcher.getWorkspace().getFirstMatch(this) != null; - } } /** diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 3c92c578d..19f7db72b 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -15,42 +15,46 @@ */ package com.android.launcher3.ui.widget; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; -import android.test.suitebuilder.annotation.LargeTest; import android.view.View; import com.android.launcher3.ItemInfo; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.Workspace.ItemOperator; -import com.android.launcher3.ui.LauncherInstrumentationTestCase; +import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.WidgetCell; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertTrue; + /** * Test to add widget from widget tray */ @LargeTest -public class AddWidgetTest extends LauncherInstrumentationTestCase { - - private LauncherAppWidgetProviderInfo widgetInfo; +@RunWith(AndroidJUnit4.class) +public class AddWidgetTest extends AbstractLauncherUiTest { - @Override - protected void setUp() throws Exception { - super.setUp(); - grantWidgetPermission(); - - widgetInfo = findWidgetProvider(false /* hasConfigureScreen */); - } + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind(); + @Test public void testDragIcon_portrait() throws Throwable { lockRotation(true); performTest(); } + @Test public void testDragIcon_landscape() throws Throwable { lockRotation(false); performTest(); @@ -58,7 +62,10 @@ public class AddWidgetTest extends LauncherInstrumentationTestCase { private void performTest() throws Throwable { clearHomescreen(); - Launcher launcher = startLauncher(); + mActivityMonitor.startLauncher(); + + final LauncherAppWidgetProviderInfo widgetInfo = + findWidgetProvider(false /* hasConfigureScreen */); // Open widget tray and wait for load complete. final UiObject2 widgetContainer = openWidgetsTray(); @@ -69,12 +76,12 @@ public class AddWidgetTest extends LauncherInstrumentationTestCase { .hasDescendant(By.text(widgetInfo.getLabel(mTargetContext.getPackageManager())))); dragToWorkspace(widget, false); - assertNotNull(launcher.getWorkspace().getFirstMatch(new ItemOperator() { + assertTrue(mActivityMonitor.itemExists(new ItemOperator() { @Override public boolean evaluate(ItemInfo info, View view) { return info instanceof LauncherAppWidgetInfo && ((LauncherAppWidgetInfo) info).providerName.equals(widgetInfo.provider); } - })); + }).call()); } } diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java index 97f7b505a..d4d517a22 100644 --- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java @@ -24,10 +24,11 @@ import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Bundle; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiSelector; -import android.test.suitebuilder.annotation.LargeTest; -import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetHostView; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; @@ -37,23 +38,40 @@ import com.android.launcher3.PendingAppWidgetHostView; import com.android.launcher3.Workspace; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.PackageInstallerCompat; -import com.android.launcher3.ui.LauncherInstrumentationTestCase; +import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.util.ContentWriter; import com.android.launcher3.util.LooperExecutor; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.PendingAddWidgetInfo; import com.android.launcher3.widget.WidgetHostViewLoader; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + /** * Tests for bind widget flow. * * Note running these tests will clear the workspace on the device. */ @LargeTest -public class BindWidgetTest extends LauncherInstrumentationTestCase { +@RunWith(AndroidJUnit4.class) +public class BindWidgetTest extends AbstractLauncherUiTest { + + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind(); private ContentResolver mResolver; private AppWidgetManagerCompat mWidgetManager; @@ -64,21 +82,20 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { private int mSessionId = -1; @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { super.setUp(); mResolver = mTargetContext.getContentResolver(); mWidgetManager = AppWidgetManagerCompat.getInstance(mTargetContext); - grantWidgetPermission(); // Clear all existing data LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB); LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); + @After + public void tearDown() throws Exception { if (mCursor != null) { mCursor.close(); } @@ -88,6 +105,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { } } + @Test public void testBindNormalWidget_withConfig() { LauncherAppWidgetProviderInfo info = findWidgetProvider(true); LauncherAppWidgetInfo item = createWidgetInfo(info, true); @@ -95,6 +113,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label); } + @Test public void testBindNormalWidget_withoutConfig() { LauncherAppWidgetProviderInfo info = findWidgetProvider(false); LauncherAppWidgetInfo item = createWidgetInfo(info, true); @@ -102,6 +121,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label); } + @Test public void testUnboundWidget_removed() throws Exception { LauncherAppWidgetProviderInfo info = findWidgetProvider(false); LauncherAppWidgetInfo item = createWidgetInfo(info, false); @@ -120,6 +140,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { assertFalse(mDevice.findObject(new UiSelector().description(info.label)).exists()); } + @Test public void testPendingWidget_autoRestored() { // A non-restored widget with no config screen gets restored automatically. LauncherAppWidgetProviderInfo info = findWidgetProvider(false); @@ -131,6 +152,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label); } + @Test public void testPendingWidget_withConfigScreen() throws Exception { // A non-restored widget with config screen get bound and shows a 'Click to setup' UI. LauncherAppWidgetProviderInfo info = findWidgetProvider(true); @@ -153,6 +175,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { LauncherSettings.Favorites.APPWIDGET_ID)))); } + @Test public void testPendingWidget_notRestored_removed() throws Exception { LauncherAppWidgetInfo item = getInvalidWidgetInfo(); item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID @@ -169,6 +192,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { assertEquals(0, mCursor.getCount()); } + @Test public void testPendingWidget_notRestored_brokenInstall() throws Exception { // A widget which is was being installed once, even if its not being // installed at the moment is not removed. @@ -191,6 +215,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID); } + @Test public void testPendingWidget_notRestored_activeInstall() throws Exception { // A widget which is being installed is not removed LauncherAppWidgetInfo item = getInvalidWidgetInfo(); @@ -249,7 +274,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { resetLoaderState(); // Launch the home activity - startLauncher(); + mActivityMonitor.startLauncher(); // Verify UI UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName()) .className(widgetClass); @@ -285,7 +310,7 @@ public class BindWidgetTest extends LauncherInstrumentationTestCase { pendingInfo.minSpanY = item.minSpanY; Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(mTargetContext, pendingInfo); - AppWidgetHost host = new AppWidgetHost(mTargetContext, Launcher.APPWIDGET_HOST_ID); + AppWidgetHost host = new LauncherAppWidgetHost(mTargetContext); int widgetId = host.allocateAppWidgetId(); if (!mWidgetManager.bindAppWidgetIdIfAllowed(widgetId, info, options)) { host.deleteAppWidgetId(widgetId); diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java index b798dfa88..4b9d83f8a 100644 --- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java +++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java @@ -15,23 +15,20 @@ */ package com.android.launcher3.ui.widget; -import android.app.Activity; -import android.app.Application; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.Intent; import android.graphics.Color; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; -import android.test.suitebuilder.annotation.LargeTest; import android.view.View; import com.android.launcher3.ItemInfo; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherSettings.Favorites; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; @@ -40,50 +37,48 @@ import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.testcomponent.AppWidgetNoConfig; import com.android.launcher3.testcomponent.AppWidgetWithConfig; import com.android.launcher3.testcomponent.RequestPinItemActivity; -import com.android.launcher3.ui.LauncherInstrumentationTestCase; +import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.util.Condition; -import com.android.launcher3.util.SimpleActivityMonitor; import com.android.launcher3.util.Wait; +import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.WidgetCell; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.util.UUID; -import java.util.concurrent.Callable; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; /** * Test to verify pin item request flow. */ @LargeTest -public class RequestPinItemTest extends LauncherInstrumentationTestCase { +@RunWith(AndroidJUnit4.class) +public class RequestPinItemTest extends AbstractLauncherUiTest { - private SimpleActivityMonitor mActivityMonitor; - private MainThreadExecutor mMainThreadExecutor; + @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); + @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind(); + @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher(); private String mCallbackAction; private String mShortcutId; private int mAppWidgetId; @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { super.setUp(); - grantWidgetPermission(); - setDefaultLauncher(); - - mActivityMonitor = new SimpleActivityMonitor(); - ((Application) getInstrumentation().getTargetContext().getApplicationContext()) - .registerActivityLifecycleCallbacks(mActivityMonitor); - mMainThreadExecutor = new MainThreadExecutor(); - mCallbackAction = UUID.randomUUID().toString(); mShortcutId = UUID.randomUUID().toString(); } - @Override - protected void tearDown() throws Exception { - ((Application) getInstrumentation().getTargetContext().getApplicationContext()) - .unregisterActivityLifecycleCallbacks(mActivityMonitor); - super.tearDown(); - } - + @Test public void testPinWidgetNoConfig() throws Throwable { runTest("pinWidgetNoConfig", true, new ItemOperator() { @Override @@ -96,6 +91,7 @@ public class RequestPinItemTest extends LauncherInstrumentationTestCase { }); } + @Test public void testPinWidgetNoConfig_customPreview() throws Throwable { // Command to set custom preview Intent command = RequestPinItemActivity.getCommandIntent( @@ -113,6 +109,7 @@ public class RequestPinItemTest extends LauncherInstrumentationTestCase { }, command); } + @Test public void testPinWidgetWithConfig() throws Throwable { runTest("pinWidgetWithConfig", true, new ItemOperator() { @Override @@ -125,6 +122,7 @@ public class RequestPinItemTest extends LauncherInstrumentationTestCase { }); } + @Test public void testPinShortcut() throws Throwable { // Command to set the shortcut id Intent command = RequestPinItemActivity.getCommandIntent( @@ -149,7 +147,7 @@ public class RequestPinItemTest extends LauncherInstrumentationTestCase { lockRotation(true); clearHomescreen(); - startLauncher(); + mActivityMonitor.startLauncher(); // Open all apps and wait for load complete final UiObject2 appsContainer = openAllApps(); @@ -191,14 +189,14 @@ public class RequestPinItemTest extends LauncherInstrumentationTestCase { } // Go back to home - mTargetContext.startActivity(getHomeIntent()); + mActivityMonitor.returnToHome(); assertTrue(Wait.atMost(new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT)); } /** * Condition for for an item */ - private class ItemSearchCondition extends Condition implements Callable<Boolean> { + private class ItemSearchCondition extends Condition { private final ItemOperator mOp; @@ -208,22 +206,7 @@ public class RequestPinItemTest extends LauncherInstrumentationTestCase { @Override public boolean isTrue() throws Throwable { - return mMainThreadExecutor.submit(this).get(); - } - - @Override - public Boolean call() throws Exception { - // Find the resumed launcher - Launcher launcher = null; - for (Activity a : mActivityMonitor.resumed) { - if (a instanceof Launcher) { - launcher = (Launcher) a; - } - } - if (launcher == null) { - return false; - } - return launcher.getWorkspace().getFirstMatch(mOp) != null; + return mMainThreadExecutor.submit(mActivityMonitor.itemExists(mOp)).get(); } } } diff --git a/tests/src/com/android/launcher3/util/SimpleActivityMonitor.java b/tests/src/com/android/launcher3/util/SimpleActivityMonitor.java deleted file mode 100644 index 6154ab6c5..000000000 --- a/tests/src/com/android/launcher3/util/SimpleActivityMonitor.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.app.Activity; -import android.app.Application.*; -import android.os.Bundle; - -import java.util.ArrayList; - -/** - * Simple monitor to keep a list of active activities. - */ -public class SimpleActivityMonitor implements ActivityLifecycleCallbacks { - - public final ArrayList<Activity> created = new ArrayList<>(); - public final ArrayList<Activity> started = new ArrayList<>(); - public final ArrayList<Activity> resumed = new ArrayList<>(); - - @Override - public void onActivityCreated(Activity activity, Bundle bundle) { - created.add(activity); - } - - @Override - public void onActivityStarted(Activity activity) { - started.add(activity); - } - - @Override - public void onActivityResumed(Activity activity) { - resumed.add(activity); - } - - @Override - public void onActivityPaused(Activity activity) { - resumed.remove(activity); - } - - @Override - public void onActivityStopped(Activity activity) { - started.remove(activity); - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { } - - @Override - public void onActivityDestroyed(Activity activity) { - created.remove(activity); - } -} diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java new file mode 100644 index 000000000..edd152a2c --- /dev/null +++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java @@ -0,0 +1,132 @@ +/* + * 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.rule; + +import android.app.Activity; +import android.app.Application; +import android.app.Application.ActivityLifecycleCallbacks; +import android.content.Intent; +import android.os.Bundle; +import android.support.test.InstrumentationRegistry; + +import com.android.launcher3.Launcher; +import com.android.launcher3.Workspace.ItemOperator; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.concurrent.Callable; + +/** + * Test rule to get the current Launcher activity. + */ +public class LauncherActivityRule implements TestRule { + + private Launcher mActivity; + + @Override + public Statement apply(Statement base, Description description) { + return new MyStatement(base); + } + + public Launcher getActivity() { + return mActivity; + } + + public Callable<Boolean> itemExists(final ItemOperator op) { + return new Callable<Boolean>() { + + @Override + public Boolean call() throws Exception { + Launcher launcher = getActivity(); + if (launcher == null) { + return false; + } + return launcher.getWorkspace().getFirstMatch(op) != null; + } + }; + } + + /** + * Starts the launcher activity in the target package. + */ + public void startLauncher() { + InstrumentationRegistry.getInstrumentation().startActivitySync(getHomeIntent()); + } + + public void returnToHome() { + InstrumentationRegistry.getTargetContext().startActivity(getHomeIntent()); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } + + public static Intent getHomeIntent() { + return new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_HOME) + .setPackage(InstrumentationRegistry.getTargetContext().getPackageName()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + + private class MyStatement extends Statement implements ActivityLifecycleCallbacks { + + private final Statement mBase; + + public MyStatement(Statement base) { + mBase = base; + } + + @Override + public void evaluate() throws Throwable { + Application app = (Application) + InstrumentationRegistry.getTargetContext().getApplicationContext(); + app.registerActivityLifecycleCallbacks(this); + try { + mBase.evaluate(); + } finally { + app.unregisterActivityLifecycleCallbacks(this); + } + } + + @Override + public void onActivityCreated(Activity activity, Bundle bundle) { + if (activity instanceof Launcher) { + mActivity = (Launcher) activity; + } + } + + @Override + public void onActivityStarted(Activity activity) { } + + @Override + public void onActivityResumed(Activity activity) { } + + @Override + public void onActivityPaused(Activity activity) { } + + @Override + public void onActivityStopped(Activity activity) { } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { } + + @Override + public void onActivityDestroyed(Activity activity) { + if (activity == mActivity) { + mActivity = null; + } + } + } +} diff --git a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java new file mode 100644 index 000000000..dba2d7100 --- /dev/null +++ b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java @@ -0,0 +1,90 @@ +/* + * 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.rule; + +import android.content.ComponentName; +import android.content.pm.ActivityInfo; +import android.os.ParcelFileDescriptor; +import android.support.test.InstrumentationRegistry; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.FileInputStream; +import java.io.IOException; + +/** + * Test rule which executes a shell command at the start of the test. + */ +public class ShellCommandRule implements TestRule { + + private final String mCmd; + + public ShellCommandRule(String cmd) { + mCmd = cmd; + } + + @Override + public Statement apply(Statement base, Description description) { + return new MyStatement(base, mCmd); + } + + public static void runShellCommand(String command) throws IOException { + ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation() + .executeShellCommand(command); + + // Read the input stream fully. + FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); + while (fis.read() != -1); + fis.close(); + } + + private static class MyStatement extends Statement { + private final Statement mBase; + private final String mCmd; + + public MyStatement(Statement base, String cmd) { + mBase = base; + mCmd = cmd; + } + + @Override + public void evaluate() throws Throwable { + runShellCommand(mCmd); + mBase.evaluate(); + } + } + + /** + * Grants the launcher permission to bind widgets. + */ + public static ShellCommandRule grandWidgetBind() { + return new ShellCommandRule("appwidget grantbind --package " + + InstrumentationRegistry.getTargetContext().getPackageName()); + } + + /** + * Sets the target launcher as default launcher. + */ + public static ShellCommandRule setDefaultLauncher() { + ActivityInfo launcher = InstrumentationRegistry.getTargetContext().getPackageManager() + .queryIntentActivities(LauncherActivityRule.getHomeIntent(), 0).get(0) + .activityInfo; + return new ShellCommandRule("cmd package set-home-activity " + + new ComponentName(launcher.packageName, launcher.name).flattenToString()); + } +} |