diff --git a/Android.mk b/Android.mk
index d41e184f0a..a63ab05c28 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,6 +16,18 @@
LOCAL_PATH := $(call my-dir)
+#
+# Prebuilt Java Libraries
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := libSharedSystemUI
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := quickstep/libs/sysui_shared.jar
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_SDK_VERSION := current
+include $(BUILD_PREBUILT)
+
#
# Build rule for Launcher3 app.
#
@@ -24,21 +36,26 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-v4 \
+ android-support-annotations
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ android-support-compat \
+ android-support-media-compat \
+ android-support-core-utils \
+ android-support-core-ui \
+ android-support-fragment \
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, src_ui_overrides) \
$(call all-java-files-under, src_flags) \
$(call all-proto-files-under, protos) \
$(call all-proto-files-under, proto_overrides)
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res \
- prebuilts/sdk/current/support/v7/recyclerview/res \
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
@@ -46,9 +63,7 @@ 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_USE_AAPT2 := true
LOCAL_SDK_VERSION := current
LOCAL_MIN_SDK_VERSION := 21
@@ -70,14 +85,20 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-v4 \
+ android-support-annotations
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ android-support-compat \
+ android-support-media-compat \
+ android-support-core-utils \
+ android-support-core-ui \
+ android-support-fragment \
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, src_ui_overrides) \
$(call all-java-files-under, go/src_flags) \
$(call all-proto-files-under, protos) \
$(call all-proto-files-under, proto_overrides)
@@ -85,7 +106,6 @@ LOCAL_SRC_FILES := \
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/go/res \
$(LOCAL_PATH)/res \
- prebuilts/sdk/current/support/v7/recyclerview/res \
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
@@ -93,9 +113,7 @@ 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_USE_AAPT2 := true
LOCAL_SDK_VERSION := current
LOCAL_MIN_SDK_VERSION := 21
@@ -114,22 +132,111 @@ LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
include $(BUILD_PACKAGE)
#
-# Launcher proto buffer jar used for development
+# Build rule for Quickstep app.
#
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-proto-files-under, protos) $(call all-proto-files-under, proto_overrides)
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-annotations \
+ libSharedSystemUI
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ android-support-compat \
+ android-support-media-compat \
+ android-support-core-utils \
+ android-support-core-ui \
+ android-support-fragment \
+ android-support-v7-recyclerview \
+ android-support-dynamic-animation
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src) \
+ $(call all-java-files-under, quickstep/src) \
+ $(call all-java-files-under, src_flags) \
+ $(call all-proto-files-under, protos) \
+ $(call all-proto-files-under, proto_overrides)
+
+LOCAL_RESOURCE_DIR := \
+ $(LOCAL_PATH)/quickstep/res \
+ $(LOCAL_PATH)/res \
+
+LOCAL_PROGUARD_ENABLED := disabled
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_MODULE_TAGS := optional
-LOCAL_MODULE := launcher_proto_lib
-LOCAL_IS_HOST_MODULE := true
-LOCAL_STATIC_JAVA_LIBRARIES := host-libprotobuf-java-nano
+LOCAL_USE_AAPT2 := true
+
+LOCAL_SDK_VERSION := system_current
+LOCAL_MIN_SDK_VERSION := 26
+LOCAL_PACKAGE_NAME := Launcher3QuickStep
+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 := quickstep/AndroidManifest.xml
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
+
+include $(BUILD_PACKAGE)
+
+#
+# Build rule for Launcher3 Go app with quickstep for Android Go devices.
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v7-recyclerview \
+ android-support-dynamic-animation \
+ libSharedSystemUI
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src) \
+ $(call all-java-files-under, quickstep/src) \
+ $(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)/quickstep/res \
+ $(LOCAL_PATH)/go/res \
+ $(LOCAL_PATH)/res \
+ prebuilts/sdk/current/support/v7/recyclerview/res \
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+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 := system_current
+LOCAL_MIN_SDK_VERSION := 26
+LOCAL_PACKAGE_NAME := Launcher3QuickStepGo
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
+
+LOCAL_FULL_LIBS_MANIFEST_FILES := \
+ $(LOCAL_PATH)/go/AndroidManifest.xml \
+ $(LOCAL_PATH)/AndroidManifest.xml \
+ $(LOCAL_PATH)/AndroidManifest-common.xml
+
+LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
+
+include $(BUILD_PACKAGE)
-include $(BUILD_HOST_JAVA_LIBRARY)
# ==================================================
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index ad404c09a9..211e1ff37f 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -20,7 +20,6 @@
-
-
diff --git a/build.gradle b/build.gradle
index 886ccace68..4ae6600ee3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,28 +1,31 @@
buildscript {
repositories {
mavenCentral()
- jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.1'
- classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
+ classpath 'com.android.tools.build:gradle:3.2.0-alpha12'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.3'
}
}
+final String SUPPORT_LIBS_VERSION = '28.0.0-SNAPSHOT'
+
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
android {
- compileSdkVersion 26
- buildToolsVersion '26.0.0'
+ compileSdkVersion 28
+ buildToolsVersion '28.0.0'
defaultConfig {
minSdkVersion 21
- targetSdkVersion 26
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ vectorDrawables.useSupportLibrary = true
}
buildTypes {
debug {
@@ -30,17 +33,40 @@ android {
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ flavorDimensions "default"
+
productFlavors {
aosp {
+ dimension "default"
applicationId 'com.android.launcher3'
testApplicationId 'com.android.launcher3.tests'
}
l3go {
+ dimension "default"
+ applicationId 'com.android.launcher3'
+ testApplicationId 'com.android.launcher3.tests'
+ }
+
+ quickstep {
+ dimension "default"
applicationId 'com.android.launcher3'
testApplicationId 'com.android.launcher3.tests'
}
}
+
+ // Disable release builds for now
+ android.variantFilter { variant ->
+ if (variant.buildType.name.endsWith('release')) {
+ variant.setIgnore(true);
+ }
+ }
+
sourceSets {
main {
res.srcDirs = ['res']
@@ -52,55 +78,61 @@ android {
}
}
+ debug {
+ manifest.srcFile "AndroidManifest.xml"
+ }
+
androidTest {
res.srcDirs = ['tests/res']
java.srcDirs = ['tests/src']
manifest.srcFile "tests/AndroidManifest-common.xml"
}
- aosp {
- java.srcDirs = ['src_flags']
- manifest.srcFile "AndroidManifest.xml"
+ androidTestDebug {
+ manifest.srcFile "tests/AndroidManifest.xml"
}
- aospAndroidTest {
- manifest.srcFile "tests/AndroidManifest.xml"
+ aosp {
+ java.srcDirs = ['src_flags', "src_ui_overrides"]
}
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"
+ java.srcDirs = ['go/src_flags', "src_ui_overrides"]
+ manifest.srcFile "go/AndroidManifest.xml"
}
- l3goAndroidTest {
- manifest.srcFile "tests/AndroidManifest.xml"
+ quickstep {
+ res.srcDirs = ['quickstep/res']
+ java.srcDirs = ['src_flags', 'quickstep/src']
+ manifest.srcFile "quickstep/AndroidManifest.xml"
}
}
}
repositories {
+ maven { url "../../../prebuilts/fullsdk-darwin/extras/android/m2repository" }
+ maven { url "../../../prebuilts/fullsdk-linux/extras/android/m2repository" }
mavenCentral()
- jcenter()
+ google()
}
-final String SUPPORT_LIBS_VERSION = '26.0.0-SNAPSHOT'
dependencies {
- compile "com.android.support:support-v4:${SUPPORT_LIBS_VERSION}"
- 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-7'
+ implementation "com.android.support:support-v4:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:support-dynamic-animation:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:recyclerview-v7:${SUPPORT_LIBS_VERSION}"
+ implementation 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7'
- testCompile 'junit:junit:4.12'
- 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'
- androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
- androidTestCompile "com.android.support:support-annotations:${SUPPORT_LIBS_VERSION}"
+ quickstepImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar')
+
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation "org.mockito:mockito-core:1.9.5"
+ androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
+ androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
+ androidTestImplementation 'com.android.support.test:runner:1.0.0'
+ androidTestImplementation 'com.android.support.test:rules:1.0.0'
+ androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
+ androidTestImplementation "com.android.support:support-annotations:${SUPPORT_LIBS_VERSION}"
}
protobuf {
diff --git a/go/res/values-ar/strings.xml b/go/res/values-ar/strings.xml
index 2b3b80746f..9888d0f7ca 100644
--- a/go/res/values-ar/strings.xml
+++ b/go/res/values-ar/strings.xml
@@ -20,7 +20,7 @@
"المس مع الاستمرار لاختيار اختصار."
- "يمكنك النقر نقرًا مزدوجًا مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."
+ "يمكنك النقر مرّتين مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."
"الاختصارات"
"اختصارات %1$s"
diff --git a/go/res/values-as/strings.xml b/go/res/values-as/strings.xml
new file mode 100644
index 0000000000..6b5807f97b
--- /dev/null
+++ b/go/res/values-as/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ স্পৰ্শ কৰি ৰাখক।"
+ "কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ দুবাৰ টিপি ৰাখক বা নিজৰ উপযোগিতা অনুসৰি বনোৱা কাৰ্যসমূহ ব্যৱহাৰ কৰক।"
+ "শ্বৰ্টকাটসমূহ"
+ "%1$s শ্বৰ্টকাটসমূহ"
+
diff --git a/go/res/values-be-rBY/strings.xml b/go/res/values-be-rBY/strings.xml
new file mode 100644
index 0000000000..4189e35fa0
--- /dev/null
+++ b/go/res/values-be-rBY/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."
+ "Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."
+ "Ярлыкі"
+ "Ярлыкі %1$s"
+
diff --git a/go/res/values-bn-rBD/strings.xml b/go/res/values-bn-rBD/strings.xml
new file mode 100644
index 0000000000..c56c925a29
--- /dev/null
+++ b/go/res/values-bn-rBD/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "কোনও শর্টকাট বেছে নিতে টাচ করে ধরে রাখুন।"
+ "কোনও শর্টকাট বেছে নিতে ডাবল ট্যাপ করে ধরে রাখুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন।"
+ "শর্টকাট"
+ "%1$s এর শর্টকাট"
+
diff --git a/go/res/values-bs-rBA/strings.xml b/go/res/values-bs-rBA/strings.xml
index 7042468b47..3141b9d8fd 100644
--- a/go/res/values-bs-rBA/strings.xml
+++ b/go/res/values-bs-rBA/strings.xml
@@ -20,7 +20,7 @@
"Dodirnite i držite da uzmete prečicu."
- "Dvaput dodirnite i držite da uzmete prečicu ili koristite prilagođene akcije."
+ "Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."
"Prečice"
"Prečice aplikacije %1$s"
diff --git a/go/res/values-bs/strings.xml b/go/res/values-bs/strings.xml
index 7042468b47..3141b9d8fd 100644
--- a/go/res/values-bs/strings.xml
+++ b/go/res/values-bs/strings.xml
@@ -20,7 +20,7 @@
"Dodirnite i držite da uzmete prečicu."
- "Dvaput dodirnite i držite da uzmete prečicu ili koristite prilagođene akcije."
+ "Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."
"Prečice"
"Prečice aplikacije %1$s"
diff --git a/go/res/values-et-rEE/strings.xml b/go/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000000..2513e65a33
--- /dev/null
+++ b/go/res/values-et-rEE/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Otsetee valimiseks puudutage seda pikalt."
+ "Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."
+ "Otseteed"
+ "Rakenduse %1$s otseteed"
+
diff --git a/go/res/values-eu-rES/strings.xml b/go/res/values-eu-rES/strings.xml
new file mode 100644
index 0000000000..9949ef091d
--- /dev/null
+++ b/go/res/values-eu-rES/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Eduki sakatuta lasterbide bat aukeratzeko."
+ "Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."
+ "Lasterbideak"
+ "%1$s aplikazioaren lasterbidea"
+
diff --git a/go/res/values-fa/strings.xml b/go/res/values-fa/strings.xml
index 8bc5256d16..f1584d9ff7 100644
--- a/go/res/values-fa/strings.xml
+++ b/go/res/values-fa/strings.xml
@@ -20,7 +20,7 @@
"برای انتخاب یک میانبر، لمس کنید و نگهدارید."
- "برای انتخاب یک میانبر، دو ضربه سریع بزنید و نگهدارید یا از اقدامهای سفارشی استفاده کنید."
+ "برای انتخاب میانبر، دو ضربه سریع بزنید و نگه دارید یا از کنشهای سفارشی استفاده کنید."
"میانبرها"
"میانبرهای %1$s"
diff --git a/go/res/values-gl-rES/strings.xml b/go/res/values-gl-rES/strings.xml
new file mode 100644
index 0000000000..31621d5c2c
--- /dev/null
+++ b/go/res/values-gl-rES/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Mantén premido un atallo para seleccionalo."
+ "Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."
+ "Atallos"
+ "Atallos da aplicación %1$s"
+
diff --git a/go/res/values-gu-rIN/strings.xml b/go/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000000..bdb549ff7f
--- /dev/null
+++ b/go/res/values-gu-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "એક શૉર્ટકટ ચૂંટવા ટૅપ કરી રાખો."
+ "એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરી રાખો."
+ "શૉર્ટકટ"
+ "%1$s શૉર્ટકટ"
+
diff --git a/go/res/values-hi/strings.xml b/go/res/values-hi/strings.xml
index bc057760fb..2c1650a0dd 100644
--- a/go/res/values-hi/strings.xml
+++ b/go/res/values-hi/strings.xml
@@ -20,7 +20,7 @@
"शॉर्टकट चुनने के लिए छूकर रखें."
- "शॉर्टकट चुनने के लिए डबल टैप करके रखें या कस्टम कार्रवाइयों का उपयोग करें."
+ "शॉर्टकट चुनने के लिए दो बार छूएं और कुछ देर दबाएं रखें या अपने मुताबिक कार्रवाइयों का इस्तेमाल करें."
"शॉर्टकट"
"%1$s शॉर्टकट"
diff --git a/go/res/values-hy-rAM/strings.xml b/go/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000000..4747f6df35
--- /dev/null
+++ b/go/res/values-hy-rAM/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։"
+ "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:"
+ "Դյուրանցումներ"
+ "%1$s դյուրանցումներ"
+
diff --git a/go/res/values-is-rIS/strings.xml b/go/res/values-is-rIS/strings.xml
new file mode 100644
index 0000000000..b8bb923746
--- /dev/null
+++ b/go/res/values-is-rIS/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Haltu fingri á flýtileið til að grípa hana."
+ "Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."
+ "Flýtileiðir"
+ "%1$s flýtileiðir"
+
diff --git a/go/res/values-kk-rKZ/strings.xml b/go/res/values-kk-rKZ/strings.xml
new file mode 100644
index 0000000000..e909818afc
--- /dev/null
+++ b/go/res/values-kk-rKZ/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Таңбашаны таңдау үшін оны түртіп, ұстап тұрыңыз."
+ "Таңбашаны таңдау немесе арнаулы әрекеттерді пайдалану үшін екі рет түртіп, ұстап тұрыңыз."
+ "Таңбашалар"
+ "%1$s таңбаша"
+
diff --git a/go/res/values-km-rKH/strings.xml b/go/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000000..40082a4b9d
--- /dev/null
+++ b/go/res/values-km-rKH/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "ប៉ះ ហើយចុចឲ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ។"
+ "ប៉ះពីរដង ហើយចុចឱ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"
+ "ផ្លូវកាត់"
+ "ផ្លូវកាត់សម្រាប់ %1$s"
+
diff --git a/go/res/values-kn-rIN/strings.xml b/go/res/values-kn-rIN/strings.xml
new file mode 100644
index 0000000000..9c121fd294
--- /dev/null
+++ b/go/res/values-kn-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ."
+ "ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ."
+ "ಶಾರ್ಟ್ಕಟ್ಗಳು"
+ "%1$s ಶಾರ್ಟ್ಕಟ್ಗಳು"
+
diff --git a/go/res/values-mk-rMK/strings.xml b/go/res/values-mk-rMK/strings.xml
new file mode 100644
index 0000000000..52d66b5e28
--- /dev/null
+++ b/go/res/values-mk-rMK/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Допрете двапати и задржете за да изберете кратенка."
+ "Допрете двапати и задржете за да изберете кратенка или да користите приспособени дејства."
+ "Кратенки"
+ "Кратенки за %1$s"
+
diff --git a/go/res/values-ml-rIN/strings.xml b/go/res/values-ml-rIN/strings.xml
new file mode 100644
index 0000000000..b3c12e16e1
--- /dev/null
+++ b/go/res/values-ml-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "ഒരു കുറുക്കുവഴി ചേർക്കുന്നതിന് അത് സ്പർശിച്ച് പിടിക്കുക."
+ "ഒരു കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."
+ "കുറുക്കുവഴികൾ"
+ "%1$s കുറുക്കുവഴികൾ"
+
diff --git a/go/res/values-mn-rMN/strings.xml b/go/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000000..c89dfd1bdc
--- /dev/null
+++ b/go/res/values-mn-rMN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Товчлол авах бол удаан дарна уу."
+ "Товчлол авах болон тохируулсан үйлдлийг ашиглахын тулд хоёр товшоод хүлээнэ үү."
+ "Товчлол"
+ "%1$s-н товчлол"
+
diff --git a/go/res/values-mr-rIN/strings.xml b/go/res/values-mr-rIN/strings.xml
new file mode 100644
index 0000000000..2c767b4f19
--- /dev/null
+++ b/go/res/values-mr-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."
+ "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."
+ "शॉर्टकट"
+ "%1$s शॉर्टकट"
+
diff --git a/go/res/values-ms-rMY/strings.xml b/go/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000000..42add9a197
--- /dev/null
+++ b/go/res/values-ms-rMY/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Sentuh & tahan untuk mengambil pintasan."
+ "Ketik dua kali & tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."
+ "Pintasan"
+ "Pintasan %1$s"
+
diff --git a/go/res/values-my-rMM/strings.xml b/go/res/values-my-rMM/strings.xml
new file mode 100644
index 0000000000..5784df63bf
--- /dev/null
+++ b/go/res/values-my-rMM/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "လက်ကွက်ဖြတ်လမ်းတစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ"
+ "လက်ကွက်ဖြတ်လမ်းကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန်နှစ်ချက်တို့ပြီး ဖိထားပါ။"
+ "ဖြတ်လမ်းလင့်ခ်များ"
+ "%1$s ဖြတ်လမ်းလင့်ခ်များ"
+
diff --git a/go/res/values-ne-rNP/strings.xml b/go/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000000..0be0375f3a
--- /dev/null
+++ b/go/res/values-ne-rNP/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "कुनै सटकर्ट छनौट गर्न छोइराख्नुहोस्।"
+ "कुनै सर्टकट छनौट गर्न दुईपटक ट्याप गरेर होल्ड गर्नुहोस् वा रोजेका कारबाहीहरू प्रयोग गर्नुहोस्।"
+ "सर्टकटहरू"
+ "%1$s सर्टकटहरू"
+
diff --git a/go/res/values-or/strings.xml b/go/res/values-or/strings.xml
new file mode 100644
index 0000000000..3ec8a72038
--- /dev/null
+++ b/go/res/values-or/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ଦାବି ଧରନ୍ତୁ।"
+ "ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ ଏବଂ ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ଧରି ରଖନ୍ତୁ କିମ୍ୱା କଷ୍ଟମ୍ ପ୍ରକ୍ରିୟା ବ୍ୟବହାର କରନ୍ତୁ।"
+ "ଶର୍ଟକଟ୍"
+ "%1$sର ଶର୍ଟକଟ୍"
+
diff --git a/go/res/values-pa-rIN/strings.xml b/go/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000000..c7e4abf3a8
--- /dev/null
+++ b/go/res/values-pa-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ ਜਾਂ ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"
+ "ਸ਼ਾਰਟਕੱਟ"
+ "%1$s ਸ਼ਾਰਟਕੱਟ"
+
diff --git a/go/res/values-pa/strings.xml b/go/res/values-pa/strings.xml
index f3982ab71b..c7e4abf3a8 100644
--- a/go/res/values-pa/strings.xml
+++ b/go/res/values-pa/strings.xml
@@ -20,7 +20,7 @@
"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"
- "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਡਬਲ-ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ ਜਾਂ ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ ਜਾਂ ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"
"ਸ਼ਾਰਟਕੱਟ"
"%1$s ਸ਼ਾਰਟਕੱਟ"
diff --git a/go/res/values-sq-rAL/strings.xml b/go/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000000..bb74db6b55
--- /dev/null
+++ b/go/res/values-sq-rAL/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "Prek dhe mbaj prekur për të zgjedhur një shkurtore."
+ "Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."
+ "Shkurtoret"
+ "%1$s shkurtore"
+
diff --git a/go/res/values-sw/strings.xml b/go/res/values-sw/strings.xml
index 0379ed012a..13c12e4a6c 100644
--- a/go/res/values-sw/strings.xml
+++ b/go/res/values-sw/strings.xml
@@ -20,7 +20,7 @@
"Gusa na ushikilie ili uchague njia ya mkato."
- "Gonga mara mbili na ushikilie ile uchague njia ya mkato au utumie vitendo maalum."
+ "Gusa mara mbili na ushikilie ile uchague njia ya mkato au utumie vitendo maalum."
"Njia za mkato"
"Njia za mkato za %1$s"
diff --git a/go/res/values-ta-rIN/strings.xml b/go/res/values-ta-rIN/strings.xml
new file mode 100644
index 0000000000..50059b65f9
--- /dev/null
+++ b/go/res/values-ta-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "குறுக்குவழியைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்."
+ "குறுக்குவழியை சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."
+ "குறுக்குவழிகள்"
+ "%1$s குறுக்குவழிகள்"
+
diff --git a/go/res/values-te-rIN/strings.xml b/go/res/values-te-rIN/strings.xml
new file mode 100644
index 0000000000..0bdf743342
--- /dev/null
+++ b/go/res/values-te-rIN/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "సత్వరమార్గాన్ని ఎంచుకోవడానికి తాకి & నొక్కి ఉంచండి."
+ "సత్వరమార్గాన్ని ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి &ఉంచండి."
+ "సత్వరమార్గాలు"
+ "%1$s సత్వరమార్గాలు"
+
diff --git a/go/res/values-ur-rPK/strings.xml b/go/res/values-ur-rPK/strings.xml
new file mode 100644
index 0000000000..46bd823d8e
--- /dev/null
+++ b/go/res/values-ur-rPK/strings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ "کوئی شارٹ کٹ منتخب کرنے کیلئے ٹچ کریں اور دبائے رکھیں۔"
+ "کوئی شارٹ کٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔"
+ "شارٹ کٹس"
+ "%1$s شارٹ کٹس"
+
diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml
index 487c026d6d..16d7e13cb9 100644
--- a/go/res/xml/device_profiles.xml
+++ b/go/res/xml/device_profiles.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-
+
(...);
}
+# The support library contains references to newer platform versions.
+# Don't warn about those in case this app is linking against an older
+# platform version. We know about them, and they are safe.
+-dontwarn android.support.**
+
# Proguard will strip methods required for talkback to properly scroll to
# next row when focus is on the last item of last row when using a RecyclerView
# Keep optimized and shrunk proguard to prevent issues like this when using
# support jar.
-#-keep,allowoptimization,allowshrinking class android.support.** {
-# *;
-#}
-keep class android.support.v7.widget.RecyclerView { *; }
+# LauncherAppTransitionManager
+-keep class com.android.launcher3.LauncherAppTransitionManagerImpl {
+ public (...);
+}
+
+# InstantAppResolver
+-keep class com.android.quickstep.InstantAppResolverImpl {
+ public (...);
+}
+
+# MainProcessInitializer
+-keep class com.android.quickstep.QuickstepProcessInitializer {
+ public (...);
+}
+
+# UserEventDispatcherExtension
+-keep class com.android.quickstep.logging.UserEventDispatcherExtension {
+ public (...);
+}
+
-keep interface com.android.launcher3.userevent.nano.LauncherLogProto.** {
*;
}
@@ -102,3 +124,14 @@
-keep interface com.android.launcher3.model.nano.LauncherDumpProto.** {
*;
}
+
+# Discovery bounce animation
+-keep class com.android.launcher3.allapps.DiscoveryBounce$VerticalProgressWrapper {
+ public void setProgress(float);
+ public float getProgress();
+}
+
+# BUG(70852369): Surpress additional warnings after changing from Proguard to R8
+-dontwarn android.app.**
+-dontwarn android.view.**
+-dontwarn android.os.**
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index 0bbec188db..06e6a923d4 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -55,6 +55,7 @@ message Target {
optional int32 span_y = 14 [default = 1];// Used for ItemType.WIDGET
optional int32 predictedRank = 15;
optional TargetExtension extension = 16;
+ optional TipType tip_type = 17;
}
// Used to define what type of item a Target would represent.
@@ -68,6 +69,8 @@ enum ItemType {
SEARCHBOX = 6;
EDITTEXT = 7;
NOTIFICATION = 8;
+ TASK = 9; // Each page of Recents UI (QuickStep)
+ WEB_APP = 10;
}
// Used to define what type of container a Target would represent.
@@ -78,11 +81,16 @@ enum ContainerType {
FOLDER = 3;
ALLAPPS = 4;
WIDGETS = 5;
- OVERVIEW = 6;
+ OVERVIEW = 6; // Zoomed out workspace (without QuickStep)
PREDICTION = 7;
SEARCHRESULT = 8;
DEEPSHORTCUTS = 9;
PINITEM = 10; // confirmation screen
+ NAVBAR = 11;
+ TASKSWITCHER = 12; // Recents UI Container (QuickStep)
+ APP = 13; // Foreground activity is another app (QuickStep)
+ TIP = 14; // Onboarding texts (QuickStep)
+ SIDELOADED_LAUNCHER = 15;
}
// Used to define what type of control a Target would represent.
@@ -99,7 +107,19 @@ enum ControlType {
VERTICAL_SCROLL = 9;
HOME_INTENT = 10; // Deprecated, use enum Command instead
BACK_BUTTON = 11; // Deprecated, use enum Command instead
- // GO_TO_PLAYSTORE
+ QUICK_SCRUB_BUTTON = 12;
+ CLEAR_ALL_BUTTON = 13;
+ CANCEL_TARGET = 14;
+ TASK_PREVIEW = 15;
+ SPLIT_SCREEN_TARGET = 16;
+}
+
+enum TipType {
+ DEFAULT_NONE = 0;
+ BOUNCE = 1;
+ SWIPE_UP_TEXT = 2;
+ QUICK_SCRUB_TEXT = 3;
+ PREDICTION_TEXT = 4;
}
// Used to define the action component of the LauncherEvent.
@@ -108,8 +128,10 @@ message Action {
TOUCH = 0;
AUTOMATED = 1;
COMMAND = 2;
+ TIP = 3;
// SOFT_KEYBOARD, HARD_KEYBOARD, ASSIST
}
+
enum Touch {
TAP = 0;
LONGPRESS = 1;
@@ -118,7 +140,8 @@ message Action {
FLING = 4;
PINCH = 5;
}
- enum Direction {
+
+ enum Direction {
NONE = 0;
UP = 1;
DOWN = 2;
@@ -128,17 +151,22 @@ message Action {
enum Command {
HOME_INTENT = 0;
BACK = 1;
- ENTRY = 2; // Indicates entry to one of Launcher container type target
- // not using the HOME_INTENT
- CANCEL = 3; // Indicates that a confirmation screen was cancelled
- CONFIRM = 4; // Indicates thata confirmation screen was accepted
+ ENTRY = 2; // Indicates entry to one of Launcher container type target
+ // not using the HOME_INTENT
+ CANCEL = 3; // Indicates that a confirmation screen was cancelled
+ CONFIRM = 4; // Indicates thata confirmation screen was accepted
+ STOP = 5; // Indicates onStop() was called (screen time out, power off)
+ RECENTS_BUTTON = 6; // Indicates that Recents button was pressed
+ RESUME = 7; // Indicates onResume() was called
}
+
optional Type type = 1;
optional Touch touch = 2;
optional Direction dir = 3;
optional Command command = 4;
// Log if the action was performed on outside of the container
optional bool is_outside = 5;
+ optional bool is_state_change = 6;
}
//
@@ -148,7 +176,6 @@ message Action {
//
message LauncherEvent {
required Action action = 1;
-
// List of targets that touch actions can be operated on.
repeated Target src_target = 2;
repeated Target dest_target = 3;
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
new file mode 100644
index 0000000000..778866d5ea
--- /dev/null
+++ b/quickstep/AndroidManifest.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
new file mode 100644
index 0000000000..53a6ceb4d0
Binary files /dev/null and b/quickstep/libs/sysui_shared.jar differ
diff --git a/quickstep/res/drawable/bg_workspace_card_button.xml b/quickstep/res/drawable/bg_workspace_card_button.xml
new file mode 100644
index 0000000000..3ba47bb4d1
--- /dev/null
+++ b/quickstep/res/drawable/bg_workspace_card_button.xml
@@ -0,0 +1,30 @@
+
+
+
+
+ -
+
+
+
+ -
+
+
+
diff --git a/quickstep/res/drawable/ic_empty_recents.xml b/quickstep/res/drawable/ic_empty_recents.xml
new file mode 100644
index 0000000000..5183733975
--- /dev/null
+++ b/quickstep/res/drawable/ic_empty_recents.xml
@@ -0,0 +1,30 @@
+
+
+
+
diff --git a/quickstep/res/drawable/ic_pin.xml b/quickstep/res/drawable/ic_pin.xml
new file mode 100644
index 0000000000..8c799e38ec
--- /dev/null
+++ b/quickstep/res/drawable/ic_pin.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quickstep/res/drawable/ic_split_screen.xml b/quickstep/res/drawable/ic_split_screen.xml
new file mode 100644
index 0000000000..77bd3336d2
--- /dev/null
+++ b/quickstep/res/drawable/ic_split_screen.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quickstep/res/layout/fallback_recents_activity.xml b/quickstep/res/layout/fallback_recents_activity.xml
new file mode 100644
index 0000000000..84e13add58
--- /dev/null
+++ b/quickstep/res/layout/fallback_recents_activity.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
new file mode 100644
index 0000000000..25615e0e2d
--- /dev/null
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -0,0 +1,15 @@
+
+
+
\ No newline at end of file
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
new file mode 100644
index 0000000000..840b040ac0
--- /dev/null
+++ b/quickstep/res/layout/overview_panel.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/zzz_dummy_widget.xml b/quickstep/res/layout/scrim_view.xml
similarity index 61%
rename from res/layout/zzz_dummy_widget.xml
rename to quickstep/res/layout/scrim_view.xml
index a0fa8fc3e4..2cc37f9cc4 100644
--- a/res/layout/zzz_dummy_widget.xml
+++ b/quickstep/res/layout/scrim_view.xml
@@ -1,5 +1,5 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ android:id="@+id/scrim_view" />
\ No newline at end of file
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
new file mode 100644
index 0000000000..f163872161
--- /dev/null
+++ b/quickstep/res/layout/task.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/shortcuts_item.xml b/quickstep/res/layout/task_menu.xml
similarity index 53%
rename from res/layout/shortcuts_item.xml
rename to quickstep/res/layout/task_menu.xml
index 7cd996de01..b8466652e5 100644
--- a/res/layout/shortcuts_item.xml
+++ b/quickstep/res/layout/task_menu.xml
@@ -1,5 +1,6 @@
-
-
-
-
-
-
-
-
-
+
-
-
-
+ android:layout_height="112dp"
+ android:textSize="14sp"
+ android:paddingTop="18dp"
+ android:drawablePadding="8dp"
+ android:gravity="center_horizontal"/>
+
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
new file mode 100644
index 0000000000..8ae493fb6e
--- /dev/null
+++ b/quickstep/res/values-af/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Verdeelde skerm"
+ "Speld vas"
+ "Oorsig"
+ "Geen onlangse items nie"
+ "Maak toe"
+ "Vee alles uit"
+ "Onlangse programme"
+
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
new file mode 100644
index 0000000000..4ca0c67979
--- /dev/null
+++ b/quickstep/res/values-am/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "የተከፈለ ማያ ገጽ"
+ "ሰካ"
+ "ማጠቃለያ"
+ "ምንም የቅርብ ጊዜ ንጥሎች የሉም"
+ "ዝጋ"
+ "ሁሉንም አጽዳ"
+ "የቅርብ ጊዜ መተግበሪያዎች"
+
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
new file mode 100644
index 0000000000..c04b618699
--- /dev/null
+++ b/quickstep/res/values-ar/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "تقسيم الشاشة"
+ "تثبيت"
+ "نظرة عامة"
+ "ليست هناك عناصر تم استخدامها مؤخرًا"
+ "إغلاق"
+ "محو الكل"
+ "التطبيقات التي تمّ استخدامها مؤخرًا"
+
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
new file mode 100644
index 0000000000..812a24649a
--- /dev/null
+++ b/quickstep/res/values-as/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "বিভাজিত স্ক্ৰীণ"
+ "পিন"
+ "অৱলোকন"
+ "কোনো শেহতীয়া বস্তু নাই"
+ "বন্ধ কৰক"
+ "সকলো মচক"
+ "শেহতীয়া এপসমূহ"
+
diff --git a/quickstep/res/values-az-rAZ/strings.xml b/quickstep/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000000..0546f46508
--- /dev/null
+++ b/quickstep/res/values-az-rAZ/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Bölünmüş ekran"
+ "Sancın"
+ "İcmal"
+ "Son elementlər yoxdur"
+ "Bağlayın"
+ "Hamısını silin"
+
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
new file mode 100644
index 0000000000..832ed8c5f6
--- /dev/null
+++ b/quickstep/res/values-az/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Bölünmüş ekran"
+ "Sancın"
+ "İcmal"
+ "Son elementlər yoxdur"
+ "Bağlayın"
+ "Hamısını silin"
+ "Son tətbiqlər"
+
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000000..fc4c8c0d08
--- /dev/null
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Podeljeni ekran"
+ "Zakači"
+ "Pregled"
+ "Nema nedavnih stavki"
+ "Zatvori"
+ "Obriši sve"
+ "Nedavne aplikacije"
+
diff --git a/quickstep/res/values-be-rBY/strings.xml b/quickstep/res/values-be-rBY/strings.xml
new file mode 100644
index 0000000000..1e60dd36fd
--- /dev/null
+++ b/quickstep/res/values-be-rBY/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Падзяліць экран"
+ "Замацаваць"
+ "Агляд"
+ "Няма новых элементаў"
+ "Закрыць"
+ "Ачысціць усё"
+
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
new file mode 100644
index 0000000000..c5d03d47a5
--- /dev/null
+++ b/quickstep/res/values-be/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Падзяліць экран"
+ "Замацаваць"
+ "Агляд"
+ "Няма новых элементаў"
+ "Закрыць"
+ "Ачысціць усё"
+ "Нядаўнія праграмы"
+
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
new file mode 100644
index 0000000000..2672b83653
--- /dev/null
+++ b/quickstep/res/values-bg/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Разделен екран"
+ "Фиксиране"
+ "Общ преглед"
+ "Няма скорошни елементи"
+ "Затваряне"
+ "Изчистване на всички"
+ "Скорошни приложения"
+
diff --git a/quickstep/res/values-bn-rBD/strings.xml b/quickstep/res/values-bn-rBD/strings.xml
new file mode 100644
index 0000000000..a0605d8317
--- /dev/null
+++ b/quickstep/res/values-bn-rBD/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "স্ক্রিন স্প্লিট করুন"
+ "পিন করুন"
+ "এক নজরে"
+ "কোনো সাম্প্রতিক আইটেম নেই"
+ "বন্ধ করুন"
+ "সবকিছু খালি করুন"
+
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
new file mode 100644
index 0000000000..0a824c2dd1
--- /dev/null
+++ b/quickstep/res/values-bn/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "স্ক্রিন স্প্লিট করুন"
+ "পিন করুন"
+ "এক নজরে"
+ "কোনো সাম্প্রতিক আইটেম নেই"
+ "বন্ধ করুন"
+ "সবকিছু খালি করুন"
+ "সম্প্রতি ব্যবহৃত অ্যাপ"
+
diff --git a/quickstep/res/values-bs-rBA/strings.xml b/quickstep/res/values-bs-rBA/strings.xml
new file mode 100644
index 0000000000..9ffa84806c
--- /dev/null
+++ b/quickstep/res/values-bs-rBA/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Način rada podijeljenog ekrana"
+ "Zakači"
+ "Pregled"
+ "Nema nedavnih stavki"
+ "Zatvaranje"
+ "Obriši sve"
+
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
new file mode 100644
index 0000000000..6bf38eba15
--- /dev/null
+++ b/quickstep/res/values-bs/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Način rada podijeljenog ekrana"
+ "Zakači"
+ "Pregled"
+ "Nema nedavnih stavki"
+ "Zatvaranje"
+ "Obriši sve"
+ "Nedavne aplikacije"
+
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
new file mode 100644
index 0000000000..2d51703ae4
--- /dev/null
+++ b/quickstep/res/values-ca/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Divideix la pantalla"
+ "Fixa"
+ "Aplicacions recents"
+ "No hi ha cap element recent"
+ "Tanca"
+ "Esborra-ho tot"
+ "Aplicacions recents"
+
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
new file mode 100644
index 0000000000..a178df08b4
--- /dev/null
+++ b/quickstep/res/values-cs/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Rozdělená obrazovka"
+ "PIN"
+ "Přehled"
+ "Žádné nedávné položky"
+ "Zavřít"
+ "Vymazat vše"
+ "Poslední aplikace"
+
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
new file mode 100644
index 0000000000..d0d629f5a1
--- /dev/null
+++ b/quickstep/res/values-da/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Delt skærm"
+ "Fastgør"
+ "Oversigt"
+ "Ingen nye elementer"
+ "Luk"
+ "Ryd alt"
+ "Seneste apps"
+
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
new file mode 100644
index 0000000000..aee8b85b8c
--- /dev/null
+++ b/quickstep/res/values-de/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Bildschirm teilen"
+ "Fixieren"
+ "Übersicht"
+ "Keine kürzlich verwendeten Elemente"
+ "Schließen"
+ "Alle Apps schließen"
+ "Zuletzt aktive Apps"
+
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
new file mode 100644
index 0000000000..7364b82823
--- /dev/null
+++ b/quickstep/res/values-el/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Διαχωρισμός οθόνης"
+ "Καρφίτσωμα"
+ "Επισκόπηση"
+ "Δεν υπάρχουν πρόσφατα στοιχεία"
+ "Κλείσιμο"
+ "Διαγραφή όλων"
+ "Πρόσφατες εφαρμογές"
+
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000000..d0dc1e8cb8
--- /dev/null
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Split screen"
+ "Pin"
+ "Overview"
+ "No recent items"
+ "Close"
+ "Clear all"
+ "Recent apps"
+
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000000..d0dc1e8cb8
--- /dev/null
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Split screen"
+ "Pin"
+ "Overview"
+ "No recent items"
+ "Close"
+ "Clear all"
+ "Recent apps"
+
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000000..d0dc1e8cb8
--- /dev/null
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Split screen"
+ "Pin"
+ "Overview"
+ "No recent items"
+ "Close"
+ "Clear all"
+ "Recent apps"
+
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000000..83e9d96aa1
--- /dev/null
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Pantalla dividida"
+ "Fijar"
+ "Recientes"
+ "No hay elementos recientes"
+ "Cerrar"
+ "Borrar todo"
+ "Apps recientes"
+
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
new file mode 100644
index 0000000000..e076df56ef
--- /dev/null
+++ b/quickstep/res/values-es/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Dividir pantalla"
+ "Fijar"
+ "Aplicaciones recientes"
+ "No hay elementos recientes"
+ "Cerrar"
+ "Borrar todo"
+ "Aplicaciones recientes"
+
diff --git a/quickstep/res/values-et-rEE/strings.xml b/quickstep/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000000..efa68f9c43
--- /dev/null
+++ b/quickstep/res/values-et-rEE/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Jagatud ekraan"
+ "Kinnita"
+ "Ülevaade"
+ "Hiljutisi üksusi pole"
+ "Sule"
+ "Sule kõik"
+
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
new file mode 100644
index 0000000000..85de9c0ab7
--- /dev/null
+++ b/quickstep/res/values-et/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Jagatud ekraan"
+ "Kinnita"
+ "Ülevaade"
+ "Hiljutisi üksusi pole"
+ "Sule"
+ "Sule kõik"
+ "Hiljutised rakendused"
+
diff --git a/quickstep/res/values-eu-rES/strings.xml b/quickstep/res/values-eu-rES/strings.xml
new file mode 100644
index 0000000000..d22242efab
--- /dev/null
+++ b/quickstep/res/values-eu-rES/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Zatitu pantaila"
+ "Ainguratu"
+ "Ikuspegi orokorra"
+ "Ez dago azkenaldi honetako ezer"
+ "Itxi"
+ "Garbitu guztiak"
+
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
new file mode 100644
index 0000000000..60943ccc4f
--- /dev/null
+++ b/quickstep/res/values-eu/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Zatitu pantaila"
+ "Ainguratu"
+ "Ikuspegi orokorra"
+ "Ez dago azkenaldi honetako ezer"
+ "Itxi"
+ "Garbitu guztiak"
+ "Azken aplikazioak"
+
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
new file mode 100644
index 0000000000..4a30daa30c
--- /dev/null
+++ b/quickstep/res/values-fa/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "تقسیم صفحه"
+ "پین"
+ "نمای کلی"
+ "بدون موارد اخیر"
+ "بستن"
+ "پاک کردن همه"
+ "برنامههای اخیر"
+
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
new file mode 100644
index 0000000000..8f4135001f
--- /dev/null
+++ b/quickstep/res/values-fi/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Jaettu näyttö"
+ "Kiinnitä"
+ "Viimeisimmät"
+ "Ei viimeaikaisia kohteita"
+ "Sulje"
+ "Poista kaikki"
+ "Viimeisimmät sovellukset"
+
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000000..7177996415
--- /dev/null
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Écran divisé"
+ "Épingler"
+ "Aperçu"
+ "Aucun élément récent"
+ "Fermer"
+ "Tout effacer"
+ "Applications récentes"
+
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
new file mode 100644
index 0000000000..0deb00bc35
--- /dev/null
+++ b/quickstep/res/values-fr/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Écran partagé"
+ "Épingler"
+ "Aperçu"
+ "Aucun élément récent"
+ "Fermer"
+ "Tout effacer"
+ "Applications récentes"
+
diff --git a/quickstep/res/values-gl-rES/strings.xml b/quickstep/res/values-gl-rES/strings.xml
new file mode 100644
index 0000000000..8efc773f49
--- /dev/null
+++ b/quickstep/res/values-gl-rES/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Pantalla dividida"
+ "Fixar"
+ "Visión xeral"
+ "Non hai elementos recentes"
+ "Pecha a aplicación"
+ "Borrar todo"
+
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
new file mode 100644
index 0000000000..8c217eb7bb
--- /dev/null
+++ b/quickstep/res/values-gl/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Pantalla dividida"
+ "Fixar"
+ "Visión xeral"
+ "Non hai elementos recentes"
+ "Pecha a aplicación"
+ "Borrar todo"
+ "Aplicacións recentes"
+
diff --git a/quickstep/res/values-gu-rIN/strings.xml b/quickstep/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000000..cdae86feba
--- /dev/null
+++ b/quickstep/res/values-gu-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "સ્ક્રીનને વિભાજિત કરો"
+ "પિન કરો"
+ "ઝલક"
+ "તાજેતરની કોઈ આઇટમ નથી"
+ "બંધ કરો"
+ "બધું સાફ કરો"
+
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
new file mode 100644
index 0000000000..8b9a538ed1
--- /dev/null
+++ b/quickstep/res/values-gu/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "સ્ક્રીનને વિભાજિત કરો"
+ "પિન કરો"
+ "ઝલક"
+ "તાજેતરની કોઈ આઇટમ નથી"
+ "બંધ કરો"
+ "બધું સાફ કરો"
+ "તાજેતરની ઍપ"
+
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
new file mode 100644
index 0000000000..83c31e78da
--- /dev/null
+++ b/quickstep/res/values-hi/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "स्क्रीन को दो हिस्सों में बाँटना (स्प्लिट स्क्रीन)"
+ "पिन करना"
+ "खास जानकारी"
+ "हाल ही में इस्तेमाल किया गया कोई ऐप्लिकेशन नहीं है"
+ "बंद करें"
+ "सभी ऐप्लिकेशन बंद करें"
+ "हाल ही में इस्तेमाल किए गए एेप्लिकेशन"
+
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
new file mode 100644
index 0000000000..baa8d85acb
--- /dev/null
+++ b/quickstep/res/values-hr/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Podijeljeni zaslon"
+ "Prikvači"
+ "Pregled"
+ "Nema nedavnih stavki"
+ "Zatvori"
+ "Izbriši sve"
+ "Nedavne aplikacije"
+
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
new file mode 100644
index 0000000000..d971374774
--- /dev/null
+++ b/quickstep/res/values-hu/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Osztott képernyő"
+ "Rögzítés"
+ "Áttekintés"
+ "Nincsenek mostanában használt elemek"
+ "Bezárás"
+ "Összes törlése"
+ "Legutóbbi alkalmazások"
+
diff --git a/quickstep/res/values-hy-rAM/strings.xml b/quickstep/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000000..4afae7de7d
--- /dev/null
+++ b/quickstep/res/values-hy-rAM/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Տրոհել էկրանը"
+ "Ամրացնել"
+ "Ընդհանուր տեղեկություններ"
+ "Վերջին տարրեր չկան"
+ "Փակել"
+ "Փակել բոլորը"
+
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
new file mode 100644
index 0000000000..b4b9b98095
--- /dev/null
+++ b/quickstep/res/values-hy/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Տրոհել էկրանը"
+ "Ամրացնել"
+ "Ընդհանուր տեղեկություններ"
+ "Վերջին տարրեր չկան"
+ "Փակել"
+ "Փակել բոլորը"
+ "Վերջին օգտագործած հավելվածները"
+
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
new file mode 100644
index 0000000000..787c14338e
--- /dev/null
+++ b/quickstep/res/values-in/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Layar terpisah"
+ "Pasang pin"
+ "Ringkasan"
+ "Tidak ada item yang baru dibuka"
+ "Tutup"
+ "Hapus semua"
+ "Aplikasi baru-baru ini"
+
diff --git a/quickstep/res/values-is-rIS/strings.xml b/quickstep/res/values-is-rIS/strings.xml
new file mode 100644
index 0000000000..88a92ed96e
--- /dev/null
+++ b/quickstep/res/values-is-rIS/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Skipta skjá"
+ "Festa"
+ "Yfirlit"
+ "Engin nýleg atriði"
+ "Loka"
+ "Hreinsa allt"
+
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
new file mode 100644
index 0000000000..1aface0c90
--- /dev/null
+++ b/quickstep/res/values-is/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Skipta skjá"
+ "Festa"
+ "Yfirlit"
+ "Engin nýleg atriði"
+ "Loka"
+ "Hreinsa allt"
+ "Nýleg forrit"
+
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
new file mode 100644
index 0000000000..192ec44c72
--- /dev/null
+++ b/quickstep/res/values-it/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Schermo diviso"
+ "Blocca"
+ "Panoramica"
+ "Nessun elemento recente"
+ "Chiudi"
+ "Cancella tutto"
+ "App recenti"
+
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
new file mode 100644
index 0000000000..64c35ec116
--- /dev/null
+++ b/quickstep/res/values-iw/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "מסך מפוצל"
+ "הצמדה"
+ "מסכים אחרונים"
+ "אין פריטים אחרונים"
+ "סגירה"
+ "ניקוי הכול"
+ "אפליקציות אחרונות"
+
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
new file mode 100644
index 0000000000..558112cded
--- /dev/null
+++ b/quickstep/res/values-ja/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "分割画面"
+ "固定"
+ "概要"
+ "最近のアイテムはありません"
+ "閉じる"
+ "すべてクリア"
+ "最近使ったアプリ"
+
diff --git a/quickstep/res/values-ka-rGE/strings.xml b/quickstep/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000000..6de8ed9222
--- /dev/null
+++ b/quickstep/res/values-ka-rGE/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "ეკრანის გაყოფა"
+ "ჩამაგრება"
+ "მიმოხილვა"
+ "ბოლოს გამოყენებული ერთეულები არ არის"
+ "დახურვა"
+ "ყველას გასუფთავება"
+
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
new file mode 100644
index 0000000000..5f061debb8
--- /dev/null
+++ b/quickstep/res/values-ka/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "ეკრანის გაყოფა"
+ "ჩამაგრება"
+ "მიმოხილვა"
+ "ბოლოს გამოყენებული ერთეულები არ არის"
+ "დახურვა"
+ "ყველას გასუფთავება"
+ "ბოლოდროინდელი აპები"
+
diff --git a/quickstep/res/values-kk-rKZ/strings.xml b/quickstep/res/values-kk-rKZ/strings.xml
new file mode 100644
index 0000000000..ddd4a77196
--- /dev/null
+++ b/quickstep/res/values-kk-rKZ/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Экранды бөлу"
+ "Бекіту"
+ "Шолу"
+ "Соңғы элементтер жоқ"
+ "Жабу"
+ "Барлығын өшіру"
+
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
new file mode 100644
index 0000000000..3e72130f1f
--- /dev/null
+++ b/quickstep/res/values-kk/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Экранды бөлу"
+ "Бекіту"
+ "Шолу"
+ "Соңғы элементтер жоқ"
+ "Жабу"
+ "Барлығын өшіру"
+ "Соңғы пайдаланылған қолданбалар"
+
diff --git a/quickstep/res/values-km-rKH/strings.xml b/quickstep/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000000..65c1dccee3
--- /dev/null
+++ b/quickstep/res/values-km-rKH/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "មុខងារបំបែកអេក្រង់"
+ "ដៅ"
+ "ទិដ្ឋភាពរួម"
+ "មិនមានធាតុថ្មីៗទេ"
+ "បិទ"
+ "សម្អាតទាំងអស់"
+
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
new file mode 100644
index 0000000000..6ae948258b
--- /dev/null
+++ b/quickstep/res/values-km/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "មុខងារបំបែកអេក្រង់"
+ "ដៅ"
+ "ទិដ្ឋភាពរួម"
+ "មិនមានធាតុថ្មីៗទេ"
+ "បិទ"
+ "សម្អាតទាំងអស់"
+ "កម្មវិធីថ្មីៗ"
+
diff --git a/quickstep/res/values-kn-rIN/strings.xml b/quickstep/res/values-kn-rIN/strings.xml
new file mode 100644
index 0000000000..55ccbb0260
--- /dev/null
+++ b/quickstep/res/values-kn-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "ಪರದೆಯನ್ನು ಬೇರ್ಪಡಿಸಿ"
+ "ಪಿನ್ ಮಾಡಿ"
+ "ಅವಲೋಕನ"
+ "ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ"
+ "ಮುಚ್ಚಿ"
+ "ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"
+
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
new file mode 100644
index 0000000000..591418b9c2
--- /dev/null
+++ b/quickstep/res/values-kn/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "ಪರದೆಯನ್ನು ಬೇರ್ಪಡಿಸಿ"
+ "ಪಿನ್ ಮಾಡಿ"
+ "ಅವಲೋಕನ"
+ "ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ"
+ "ಮುಚ್ಚಿ"
+ "ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"
+ "ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್ಗಳು"
+
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
new file mode 100644
index 0000000000..5b1ecbd2e7
--- /dev/null
+++ b/quickstep/res/values-ko/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "화면 분할"
+ "고정"
+ "최근 사용"
+ "최근 항목이 없습니다."
+ "닫기"
+ "모두 삭제"
+ "최근 앱"
+
diff --git a/quickstep/res/values-ky-rKG/strings.xml b/quickstep/res/values-ky-rKG/strings.xml
new file mode 100644
index 0000000000..b788693824
--- /dev/null
+++ b/quickstep/res/values-ky-rKG/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Экранды бөлүү"
+ "Кадап коюу"
+ "Сереп салуу"
+ "Акыркы колдонмолор жок"
+ "Жабуу"
+ "Баарын тазалоо"
+
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
new file mode 100644
index 0000000000..9f84037f7b
--- /dev/null
+++ b/quickstep/res/values-ky/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Экранды бөлүү"
+ "Кадап коюу"
+ "Сереп салуу"
+ "Акыркы колдонмолор жок"
+ "Жабуу"
+ "Баарын тазалоо"
+ "Акыркы колдонмолор"
+
diff --git a/quickstep/res/values-lo-rLA/strings.xml b/quickstep/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000000..a83743a7e9
--- /dev/null
+++ b/quickstep/res/values-lo-rLA/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "ແບ່ງໜ້າຈໍ"
+ "ປັກໝຸດ"
+ "ພາບຮວມ"
+ "ບໍ່ມີລາຍການຫຼ້າສຸດ"
+ "ປິດ"
+ "ລຶບລ້າງທັງໝົດ"
+
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
new file mode 100644
index 0000000000..ed1cb6e849
--- /dev/null
+++ b/quickstep/res/values-lo/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "ແບ່ງໜ້າຈໍ"
+ "ປັກໝຸດ"
+ "ພາບຮວມ"
+ "ບໍ່ມີລາຍການຫຼ້າສຸດ"
+ "ປິດ"
+ "ລຶບລ້າງທັງໝົດ"
+ "ແອັບຫຼ້າສຸດ"
+
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
new file mode 100644
index 0000000000..c16fc56bbd
--- /dev/null
+++ b/quickstep/res/values-lt/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Skaidyti ekraną"
+ "Prisegti"
+ "Apžvalga"
+ "Nėra jokių naujausių elementų"
+ "Uždaryti"
+ "Išvalyti viską"
+ "Naujausios programos"
+
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
new file mode 100644
index 0000000000..2dee41c43a
--- /dev/null
+++ b/quickstep/res/values-lv/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Sadalīt ekrānu"
+ "Piespraust"
+ "Pārskats"
+ "Nav nesenu vienumu."
+ "Aizvērt"
+ "Notīrīt visu"
+ "Pēdējās izmantotās lietotnes"
+
diff --git a/quickstep/res/values-mk-rMK/strings.xml b/quickstep/res/values-mk-rMK/strings.xml
new file mode 100644
index 0000000000..e428b4e1f8
--- /dev/null
+++ b/quickstep/res/values-mk-rMK/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Поделен екран"
+ "Прикачување"
+ "Преглед"
+ "Нема неодамнешни ставки"
+ "Затвори"
+ "Исчисти ги сите"
+
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
new file mode 100644
index 0000000000..ff16cea8cb
--- /dev/null
+++ b/quickstep/res/values-mk/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Поделен екран"
+ "Прикачување"
+ "Преглед"
+ "Нема неодамнешни ставки"
+ "Затвори"
+ "Исчисти ги сите"
+ "Неодамнешни апликации"
+
diff --git a/quickstep/res/values-ml-rIN/strings.xml b/quickstep/res/values-ml-rIN/strings.xml
new file mode 100644
index 0000000000..4cca447e7d
--- /dev/null
+++ b/quickstep/res/values-ml-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "സ്ക്രീൻ വിഭജിക്കുക"
+ "പിൻ ചെയ്യുക"
+ "അവലോകനം"
+ "സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"
+ "അവസാനിപ്പിക്കുക"
+ "എല്ലാം മായ്ക്കുക"
+
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
new file mode 100644
index 0000000000..624aded2a3
--- /dev/null
+++ b/quickstep/res/values-ml/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "സ്ക്രീൻ വിഭജിക്കുക"
+ "പിൻ ചെയ്യുക"
+ "അവലോകനം"
+ "സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"
+ "അവസാനിപ്പിക്കുക"
+ "എല്ലാം മായ്ക്കുക"
+ "സമീപകാല ആപ്പുകൾ"
+
diff --git a/quickstep/res/values-mn-rMN/strings.xml b/quickstep/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000000..f40f69e315
--- /dev/null
+++ b/quickstep/res/values-mn-rMN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Дэлгэцийг хуваах"
+ "Тогтоох"
+ "Тойм"
+ "Сүүлийн үеийн зүйл алга"
+ "Хаах"
+ "Бүгдийг устгах"
+
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
new file mode 100644
index 0000000000..f9021252bd
--- /dev/null
+++ b/quickstep/res/values-mn/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Дэлгэцийг хуваах"
+ "Тогтоох"
+ "Тойм"
+ "Сүүлийн үеийн зүйл алга"
+ "Хаах"
+ "Бүгдийг устгах"
+ "Саяхны аппууд"
+
diff --git a/quickstep/res/values-mr-rIN/strings.xml b/quickstep/res/values-mr-rIN/strings.xml
new file mode 100644
index 0000000000..938363db0f
--- /dev/null
+++ b/quickstep/res/values-mr-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "विभाजित स्क्रीन"
+ "पिन करा"
+ "अवलोकन"
+ "कोणतेही अलीकडील आयटम नाहीत"
+ "बंद"
+ "सर्व साफ करा"
+
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
new file mode 100644
index 0000000000..7a669dd647
--- /dev/null
+++ b/quickstep/res/values-mr/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "विभाजित स्क्रीन"
+ "पिन करा"
+ "अवलोकन"
+ "कोणतेही अलीकडील आयटम नाहीत"
+ "बंद"
+ "सर्व साफ करा"
+ "अलीकडील अॅप्स"
+
diff --git a/quickstep/res/values-ms-rMY/strings.xml b/quickstep/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000000..236fab25c8
--- /dev/null
+++ b/quickstep/res/values-ms-rMY/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Skrin pisah"
+ "Semat"
+ "Ikhtisar"
+ "Tiada item terbaharu"
+ "Tutup"
+ "Kosongkan semua"
+
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
new file mode 100644
index 0000000000..699586373c
--- /dev/null
+++ b/quickstep/res/values-ms/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Skrin pisah"
+ "Semat"
+ "Ikhtisar"
+ "Tiada item terbaharu"
+ "Tutup"
+ "Kosongkan semua"
+ "Apl terbaharu"
+
diff --git a/quickstep/res/values-my-rMM/strings.xml b/quickstep/res/values-my-rMM/strings.xml
new file mode 100644
index 0000000000..e44b904beb
--- /dev/null
+++ b/quickstep/res/values-my-rMM/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "မျက်နှာပြင် ခွဲ၍ပြသခြင်း"
+ "ပင်ထိုးခြင်း"
+ "အနှစ်ချုပ်"
+ "မကြာမီကဖွင့်ထားသည်များ မရှိပါ"
+ "ပိတ်ရန်"
+ "အားလုံးကို ရှင်းရန်"
+
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
new file mode 100644
index 0000000000..ae6dc7d0a0
--- /dev/null
+++ b/quickstep/res/values-my/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "မျက်နှာပြင် ခွဲ၍ပြသခြင်း"
+ "ပင်ထိုးခြင်း"
+ "အနှစ်ချုပ်"
+ "မကြာမီကဖွင့်ထားသည်များ မရှိပါ"
+ "ပိတ်ရန်"
+ "အားလုံးကို ရှင်းရန်"
+ "လတ်တလောသုံး အက်ပ်များ"
+
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
new file mode 100644
index 0000000000..cb8ee10f8e
--- /dev/null
+++ b/quickstep/res/values-nb/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Delt skjerm"
+ "Fest"
+ "Oversikt"
+ "Ingen nylige elementer"
+ "Lukk"
+ "Fjern alt"
+ "Nylige apper"
+
diff --git a/quickstep/res/values-ne-rNP/strings.xml b/quickstep/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000000..bf52604fd2
--- /dev/null
+++ b/quickstep/res/values-ne-rNP/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "स्क्रिन विभाजन गर्नुहोस्"
+ "पिन गर्नुहोस्"
+ "परिदृश्य"
+ "हालसालैको कुनै पनि वस्तु छैन"
+ "बन्द गर्नुहोस्"
+ "सबै खाली गर्नुहोस्"
+
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
new file mode 100644
index 0000000000..4efae7b080
--- /dev/null
+++ b/quickstep/res/values-ne/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "स्क्रिन विभाजन गर्नुहोस्"
+ "पिन गर्नुहोस्"
+ "परिदृश्य"
+ "हालसालैको कुनै पनि वस्तु छैन"
+ "बन्द गर्नुहोस्"
+ "सबै खाली गर्नुहोस्"
+ "हालसालैका अनुप्रयोगहरू"
+
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
new file mode 100644
index 0000000000..8ef2a5d5ce
--- /dev/null
+++ b/quickstep/res/values-nl/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Gesplitst scherm"
+ "Vastzetten"
+ "Overzicht"
+ "Geen recente items"
+ "Sluiten"
+ "Alles wissen"
+ "Recente apps"
+
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
new file mode 100644
index 0000000000..6895ef5f5f
--- /dev/null
+++ b/quickstep/res/values-or/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "ସ୍କ୍ରୀନ୍କୁ ଭାଗ କରନ୍ତୁ"
+ "ପିନ୍"
+ "ସଂକ୍ଷିପ୍ତ ବିବରଣ"
+ "କୌଣସି ସାମ୍ପ୍ରତିକ ଆଇଟମ୍ ନାହିଁ"
+ "ବନ୍ଦ କରନ୍ତୁ"
+ "ସବୁ ଖାଲି କରନ୍ତୁ"
+ "ସାମ୍ପ୍ରତିକ ଆପ୍"
+
diff --git a/quickstep/res/values-pa-rIN/strings.xml b/quickstep/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000000..bc044c808f
--- /dev/null
+++ b/quickstep/res/values-pa-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "ਸਪਲਿਟ ਸਕ੍ਰੀਨ"
+ "ਪਿੰਨ ਕਰੋ"
+ "ਰੂਪ-ਰੇਖਾ"
+ "ਕੋਈ ਹਾਲੀਆ ਆਈਟਮਾਂ ਨਹੀਂ"
+ "ਬੰਦ ਕਰੋ"
+ "ਸਭ ਕਲੀਅਰ ਕਰੋ"
+
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
new file mode 100644
index 0000000000..4159c30b3f
--- /dev/null
+++ b/quickstep/res/values-pa/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "ਸਪਲਿਟ ਸਕ੍ਰੀਨ"
+ "ਪਿੰਨ ਕਰੋ"
+ "ਰੂਪ-ਰੇਖਾ"
+ "ਕੋਈ ਹਾਲੀਆ ਆਈਟਮਾਂ ਨਹੀਂ"
+ "ਬੰਦ ਕਰੋ"
+ "ਸਭ ਕਲੀਅਰ ਕਰੋ"
+ "ਹਾਲੀਆ ਐਪਾਂ"
+
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
new file mode 100644
index 0000000000..cf15abd171
--- /dev/null
+++ b/quickstep/res/values-pl/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Podziel ekran"
+ "Przypnij"
+ "Przegląd"
+ "Brak ostatnich elementów"
+ "Zamknij"
+ "Wyczyść wszystko"
+ "Ostatnie aplikacje"
+
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000000..36c7e3c455
--- /dev/null
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Ecrã dividido"
+ "Fixar"
+ "Vista geral"
+ "Nenhum item recente"
+ "Fechar"
+ "Limpar tudo"
+ "Aplicações recentes"
+
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
new file mode 100644
index 0000000000..41f53f0e98
--- /dev/null
+++ b/quickstep/res/values-pt/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Tela dividida"
+ "Fixar"
+ "Visão geral"
+ "Nenhum item recente"
+ "Fechar"
+ "Limpar tudo"
+ "Apps recentes"
+
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
new file mode 100644
index 0000000000..032d886fb1
--- /dev/null
+++ b/quickstep/res/values-ro/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Ecran divizat"
+ "Fixați"
+ "Recente"
+ "Niciun element recent"
+ "Închideți"
+ "Ștergeți tot"
+ "Aplicații recente"
+
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
new file mode 100644
index 0000000000..6a218fc6b8
--- /dev/null
+++ b/quickstep/res/values-ru/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Разделить экран"
+ "Блокировать"
+ "Обзор"
+ "Здесь пока ничего нет."
+ "Закрыть"
+ "Очистить все"
+ "Недавние приложения"
+
diff --git a/quickstep/res/values-si-rLK/strings.xml b/quickstep/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000000..61bb8ba81c
--- /dev/null
+++ b/quickstep/res/values-si-rLK/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "බෙදුම් තිරය"
+ "අමුණන්න"
+ "දළ විශ්ලේෂණය"
+ "මෑත අයිතම නැත"
+ "වසන්න"
+ "සියල්ල හිස් කරන්න"
+
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
new file mode 100644
index 0000000000..c01211ac51
--- /dev/null
+++ b/quickstep/res/values-si/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "බෙදුම් තිරය"
+ "අමුණන්න"
+ "දළ විශ්ලේෂණය"
+ "මෑත අයිතම නැත"
+ "වසන්න"
+ "සියල්ල හිස් කරන්න"
+ "මෑත යෙදුම්"
+
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
new file mode 100644
index 0000000000..2cd394208e
--- /dev/null
+++ b/quickstep/res/values-sk/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Rozdeliť obrazovku"
+ "Pripnúť"
+ "Prehľad"
+ "Žiadne nedávne položky"
+ "Zavrieť"
+ "Vymazať všetko"
+ "Nedávne aplikácie"
+
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
new file mode 100644
index 0000000000..06eb95d863
--- /dev/null
+++ b/quickstep/res/values-sl/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Razdeljen zaslon"
+ "Pripni"
+ "Pregled"
+ "Ni nedavnih elementov"
+ "Zapri"
+ "Počisti vse"
+ "Nedavne aplikacije"
+
diff --git a/quickstep/res/values-sq-rAL/strings.xml b/quickstep/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000000..a0c3d781d0
--- /dev/null
+++ b/quickstep/res/values-sq-rAL/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Ekrani i ndarë"
+ "Gozhdo"
+ "Përmbledhja"
+ "Nuk ka asnjë artikull të fundit"
+ "Mbyll"
+ "Pastroji të gjitha"
+
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
new file mode 100644
index 0000000000..00231e1340
--- /dev/null
+++ b/quickstep/res/values-sq/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Ekrani i ndarë"
+ "Gozhdo"
+ "Përmbledhja"
+ "Nuk ka asnjë artikull të fundit"
+ "Mbyll"
+ "Pastroji të gjitha"
+ "Aplikacionet e fundit"
+
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
new file mode 100644
index 0000000000..0077ee244c
--- /dev/null
+++ b/quickstep/res/values-sr/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Подељени екран"
+ "Закачи"
+ "Преглед"
+ "Нема недавних ставки"
+ "Затвори"
+ "Обриши све"
+ "Недавне апликације"
+
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
new file mode 100644
index 0000000000..f05d79f2af
--- /dev/null
+++ b/quickstep/res/values-sv/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Delad skärm"
+ "Fäst"
+ "Översikt"
+ "Listan med de senaste åtgärderna är tom"
+ "Stäng"
+ "Rensa alla"
+ "Senaste apparna"
+
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
new file mode 100644
index 0000000000..e6ce953dbd
--- /dev/null
+++ b/quickstep/res/values-sw/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Gawa skrini"
+ "Bandika"
+ "Muhtasari"
+ "Hakuna vipengee vya hivi karibuni"
+ "Funga"
+ "Ondoa zote"
+ "Programu za hivi karibuni"
+
diff --git a/quickstep/res/values-ta-rIN/strings.xml b/quickstep/res/values-ta-rIN/strings.xml
new file mode 100644
index 0000000000..0c800ca720
--- /dev/null
+++ b/quickstep/res/values-ta-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "திரைப் பிரிப்பு"
+ "பின் செய்தல்"
+ "மேலோட்டப் பார்வை"
+ "சமீபத்தியவை எதுவுமில்லை"
+ "மூடும்"
+ "எல்லாம் அழி"
+
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
new file mode 100644
index 0000000000..19518e1810
--- /dev/null
+++ b/quickstep/res/values-ta/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "திரைப் பிரிப்பு"
+ "பின் செய்தல்"
+ "மேலோட்டப் பார்வை"
+ "சமீபத்தியவை எதுவுமில்லை"
+ "மூடும்"
+ "எல்லாம் அழி"
+ "சமீபத்திய ஆப்ஸ்"
+
diff --git a/quickstep/res/values-te-rIN/strings.xml b/quickstep/res/values-te-rIN/strings.xml
new file mode 100644
index 0000000000..416fbb848d
--- /dev/null
+++ b/quickstep/res/values-te-rIN/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "స్క్రీన్ని విభజించు"
+ "పిన్ చేయి"
+ "అవలోకనం"
+ "ఇటీవలి అంశాలు ఏవీ లేవు"
+ "మూసివేయండి"
+ "అన్నీ తీసివేయండి"
+
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
new file mode 100644
index 0000000000..4c0e5ac563
--- /dev/null
+++ b/quickstep/res/values-te/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "స్క్రీన్ని విభజించు"
+ "పిన్ చేయి"
+ "అవలోకనం"
+ "ఇటీవలి అంశాలు ఏవీ లేవు"
+ "మూసివేయండి"
+ "అన్నీ తీసివేయండి"
+ "ఇటీవలి యాప్లు"
+
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
new file mode 100644
index 0000000000..8dfda248c3
--- /dev/null
+++ b/quickstep/res/values-th/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "แยกหน้าจอ"
+ "ตรึง"
+ "ภาพรวม"
+ "ไม่มีรายการล่าสุด"
+ "ปิด"
+ "ล้างทั้งหมด"
+ "แอปล่าสุด"
+
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
new file mode 100644
index 0000000000..ab3cac9dc2
--- /dev/null
+++ b/quickstep/res/values-tl/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Hatiin ang screen"
+ "I-pin"
+ "Overview"
+ "Walang kamakailang item"
+ "Isara"
+ "I-clear lahat"
+ "Mga kamakailang app"
+
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
new file mode 100644
index 0000000000..9693413034
--- /dev/null
+++ b/quickstep/res/values-tr/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Bölünmüş ekran"
+ "Sabitle"
+ "Genel bakış"
+ "Yeni öğe yok"
+ "Kapat"
+ "Tümünü temizle"
+ "Son uygulamalar"
+
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
new file mode 100644
index 0000000000..2afcb31865
--- /dev/null
+++ b/quickstep/res/values-uk/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Розділити екран"
+ "Закріпити"
+ "Огляд"
+ "Немає нещодавніх додатків"
+ "Закрити"
+ "Очистити все"
+ "Нещодавні додатки"
+
diff --git a/quickstep/res/values-ur-rPK/strings.xml b/quickstep/res/values-ur-rPK/strings.xml
new file mode 100644
index 0000000000..0a546fd603
--- /dev/null
+++ b/quickstep/res/values-ur-rPK/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "اسپلٹ اسکرین وضع"
+ "پن کریں"
+ "مجموعی جائزہ"
+ "کوئی حالیہ آئٹم نہیں"
+ "بند کریں"
+ "سبھی کو صاف کریں"
+
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
new file mode 100644
index 0000000000..f493a2f64d
--- /dev/null
+++ b/quickstep/res/values-ur/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "اسپلٹ اسکرین وضع"
+ "پن کریں"
+ "مجموعی جائزہ"
+ "کوئی حالیہ آئٹم نہیں"
+ "بند کریں"
+ "سبھی کو صاف کریں"
+ "حالیہ ایپس"
+
diff --git a/quickstep/res/values-uz-rUZ/strings.xml b/quickstep/res/values-uz-rUZ/strings.xml
new file mode 100644
index 0000000000..efea34117f
--- /dev/null
+++ b/quickstep/res/values-uz-rUZ/strings.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ "Ekranni ikkiga ajratish"
+ "Mahkamlash"
+ "Nazar"
+ "Yaqinda ishlatilgan ilovalar yo‘q"
+ "Yopish"
+ "Hammasini tozalash"
+
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
new file mode 100644
index 0000000000..4911925984
--- /dev/null
+++ b/quickstep/res/values-uz/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Ekranni ikkiga ajratish"
+ "Mahkamlash"
+ "Nazar"
+ "Yaqinda ishlatilgan ilovalar yo‘q"
+ "Yopish"
+ "Hammasini tozalash"
+ "Yaqinda ishlatilgan ilovalar"
+
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
new file mode 100644
index 0000000000..406faf5f8c
--- /dev/null
+++ b/quickstep/res/values-vi/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Chia đôi màn hình"
+ "Ghim"
+ "Tổng quan"
+ "Không có mục gần đây nào"
+ "Đóng"
+ "Xóa tất cả"
+ "Ứng dụng gần đây"
+
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000000..71ac114979
--- /dev/null
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "分屏"
+ "固定"
+ "概览"
+ "近期没有任何内容"
+ "关闭"
+ "全部清除"
+ "最近用过的应用"
+
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000000..ab29a91bfe
--- /dev/null
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "分割畫面"
+ "固定"
+ "概覽"
+ "最近沒有任何項目"
+ "關閉"
+ "全部清除"
+ "最近使用的應用程式"
+
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000000..1a9448c59f
--- /dev/null
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "分割畫面"
+ "固定"
+ "總覽"
+ "最近沒有任何項目"
+ "關閉"
+ "全部清除"
+ "最近使用的應用程式"
+
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
new file mode 100644
index 0000000000..3d4f37250a
--- /dev/null
+++ b/quickstep/res/values-zu/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ "Hlukanisa isikrini"
+ "Phina"
+ "Buka konke"
+ "Azikho izinto zakamuva"
+ "Vala"
+ "Sula konke"
+ "Izinhlelo zokusebenza zakamuva"
+
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
new file mode 100644
index 0000000000..c294376340
--- /dev/null
+++ b/quickstep/res/values/config.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+ com.android.quickstep.logging.UserEventDispatcherExtension
+
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
new file mode 100644
index 0000000000..ed18bf5e3a
--- /dev/null
+++ b/quickstep/res/values/dimens.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+ 24dp
+ 48dp
+ 12dp
+ 2dp
+ 10dp
+ 20dp
+
+
+ 600dp
+
+ 500dp
+ 250dp
+
+
+ 50dp
+ 50dp
+ 115dp
+
+ 16sp
+ 16dp
+
+
+ 40dp
+ 136dp
+ 200dp
+ 100dp
+
+ 10dp
+
+
+ 168dp
+
+ 16dp
+
diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml
new file mode 100644
index 0000000000..d6836594f4
--- /dev/null
+++ b/quickstep/res/values/override.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ com.android.launcher3.LauncherAppTransitionManagerImpl
+
+ com.android.quickstep.InstantAppResolverImpl
+
+ com.android.quickstep.QuickstepProcessInitializer
+
+
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
new file mode 100644
index 0000000000..a76899d3da
--- /dev/null
+++ b/quickstep/res/values/strings.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+ Quickstep
+
+
+
+ Split screen
+
+ Pin
+
+
+ Overview
+
+
+ No recent items
+
+
+ Close
+
+
+ Clear all
+
+
+ Recent apps
+
\ No newline at end of file
diff --git a/quickstep/res/xml/indexable_launcher_prefs.xml b/quickstep/res/xml/indexable_launcher_prefs.xml
new file mode 100644
index 0000000000..30f310021f
--- /dev/null
+++ b/quickstep/res/xml/indexable_launcher_prefs.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
new file mode 100644
index 0000000000..e34631042d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 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 static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
+import static com.android.launcher3.Utilities.postAsyncCallback;
+import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.os.Handler;
+import android.support.annotation.BinderThread;
+import android.support.annotation.UiThread;
+
+import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+
+@TargetApi(Build.VERSION_CODES.P)
+public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
+
+ private final Handler mHandler;
+ private final boolean mStartAtFrontOfQueue;
+ private AnimationResult mAnimationResult;
+
+ /**
+ * @param startAtFrontOfQueue If true, the animation start will be posted at the front of the
+ * queue to minimize latency.
+ */
+ public LauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue) {
+ mHandler = handler;
+ mStartAtFrontOfQueue = startAtFrontOfQueue;
+ }
+
+ @BinderThread
+ @Override
+ public void onAnimationStart(RemoteAnimationTargetCompat[] targetCompats, Runnable runnable) {
+ Runnable r = () -> {
+ finishExistingAnimation();
+ mAnimationResult = new AnimationResult(runnable);
+ onCreateAnimation(targetCompats, mAnimationResult);
+ };
+ if (mStartAtFrontOfQueue) {
+ postAtFrontOfQueueAsynchronously(mHandler, r);
+ } else {
+ postAsyncCallback(mHandler, r);
+ }
+ }
+
+ /**
+ * Called on the UI thread when the animation targets are received. The implementation must
+ * call {@link AnimationResult#setAnimation(AnimatorSet)} with the target animation to be run.
+ */
+ @UiThread
+ public abstract void onCreateAnimation(
+ RemoteAnimationTargetCompat[] targetCompats, AnimationResult result);
+
+ @UiThread
+ private void finishExistingAnimation() {
+ if (mAnimationResult != null) {
+ mAnimationResult.finish();
+ mAnimationResult = null;
+ }
+ }
+
+ /**
+ * Called by the system
+ */
+ @BinderThread
+ @Override
+ public void onAnimationCancelled() {
+ postAsyncCallback(mHandler, this::finishExistingAnimation);
+ }
+
+ public static final class AnimationResult {
+
+ private final Runnable mFinishRunnable;
+
+ private AnimatorSet mAnimator;
+ private boolean mFinished = false;
+ private boolean mInitialized = false;
+
+ private AnimationResult(Runnable finishRunnable) {
+ mFinishRunnable = finishRunnable;
+ }
+
+ @UiThread
+ private void finish() {
+ if (!mFinished) {
+ mFinishRunnable.run();
+ mFinished = true;
+ }
+ }
+
+ @UiThread
+ public void setAnimation(AnimatorSet animation) {
+ if (mInitialized) {
+ throw new IllegalStateException("Animation already initialized");
+ }
+ mInitialized = true;
+ mAnimator = animation;
+ if (mAnimator == null) {
+ finish();
+ } else if (mFinished) {
+ // Animation callback was already finished, skip the animation.
+ mAnimator.start();
+ mAnimator.end();
+ } else {
+ // Start the animation
+ mAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finish();
+ }
+ });
+ mAnimator.start();
+
+ // Because t=0 has the app icon in its original spot, we can skip the
+ // first frame and have the same movement one frame earlier.
+ mAnimator.setCurrentPlayTime(SINGLE_FRAME_MS);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
new file mode 100644
index 0000000000..2630edb3d2
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -0,0 +1,805 @@
+/*
+ * Copyright (C) 2018 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 static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
+import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.Utilities.postAsyncCallback;
+import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
+import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
+import static com.android.quickstep.TaskUtils.findTaskViewToLaunch;
+import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
+import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
+import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
+import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.InsettableFrameLayout.LayoutParams;
+import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.graphics.DrawableFactory;
+import com.android.launcher3.shortcuts.DeepShortcutView;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.MultiValueUpdateListener;
+import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.system.ActivityCompat;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
+import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
+import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+/**
+ * Manages the opening and closing app transitions from Launcher.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+@SuppressWarnings("unused")
+public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManager
+ implements OnDeviceProfileChangeListener {
+
+ private static final String TAG = "LauncherTransition";
+ public static final int STATUS_BAR_TRANSITION_DURATION = 120;
+
+ private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
+ "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
+
+ private static final int APP_LAUNCH_DURATION = 500;
+ // Use a shorter duration for x or y translation to create a curve effect
+ private static final int APP_LAUNCH_CURVED_DURATION = APP_LAUNCH_DURATION / 2;
+ // We scale the durations for the downward app launch animations (minus the scale animation).
+ private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
+ private static final int APP_LAUNCH_ALPHA_START_DELAY = 32;
+ private static final int APP_LAUNCH_ALPHA_DURATION = 50;
+
+ public static final int RECENTS_LAUNCH_DURATION = 336;
+ public static final int RECENTS_QUICKSCRUB_LAUNCH_DURATION = 300;
+ private static final int LAUNCHER_RESUME_START_DELAY = 100;
+ private static final int CLOSING_TRANSITION_DURATION_MS = 250;
+
+ // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
+ public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f;
+
+ private final Launcher mLauncher;
+ private final DragLayer mDragLayer;
+ private final AlphaProperty mDragLayerAlpha;
+
+ private final Handler mHandler;
+ private final boolean mIsRtl;
+
+ private final float mContentTransY;
+ private final float mWorkspaceTransY;
+ private final float mClosingWindowTransY;
+
+ private DeviceProfile mDeviceProfile;
+ private View mFloatingView;
+
+ private RemoteAnimationProvider mRemoteAnimationProvider;
+
+ private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mLauncher.addForceInvisibleFlag(INVISIBLE_BY_APP_TRANSITIONS);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.clearForceInvisibleFlag(INVISIBLE_BY_APP_TRANSITIONS);
+ }
+ };
+
+ public LauncherAppTransitionManagerImpl(Context context) {
+ mLauncher = Launcher.getLauncher(context);
+ mDragLayer = mLauncher.getDragLayer();
+ mDragLayerAlpha = mDragLayer.getAlphaProperty(ALPHA_INDEX_TRANSITIONS);
+ mHandler = new Handler(Looper.getMainLooper());
+ mIsRtl = Utilities.isRtl(mLauncher.getResources());
+ mDeviceProfile = mLauncher.getDeviceProfile();
+
+ Resources res = mLauncher.getResources();
+ mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
+ mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
+ mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y);
+
+ mLauncher.addOnDeviceProfileChangeListener(this);
+ registerRemoteAnimations();
+ }
+
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ mDeviceProfile = dp;
+ }
+
+ /**
+ * @return ActivityOptions with remote animations that controls how the window of the opening
+ * targets are displayed.
+ */
+ @Override
+ public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
+ if (hasControlRemoteAppTransitionPermission()) {
+ RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler,
+ true /* startAtFrontOfQueue */) {
+
+ @Override
+ public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
+ AnimationResult result) {
+ AnimatorSet anim = new AnimatorSet();
+
+ boolean launcherClosing =
+ launcherIsATargetWithMode(targetCompats, MODE_CLOSING);
+
+ if (!composeRecentsLaunchAnimator(v, targetCompats, anim)) {
+ // Set the state animation first so that any state listeners are called
+ // before our internal listeners.
+ mLauncher.getStateManager().setCurrentAnimation(anim);
+
+ Rect windowTargetBounds = getWindowTargetBounds(targetCompats);
+ anim.play(getIconAnimator(v, windowTargetBounds));
+ if (launcherClosing) {
+ Pair launcherContentAnimator =
+ getLauncherContentAnimator(true /* isAppOpening */);
+ anim.play(launcherContentAnimator.first);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ launcherContentAnimator.second.run();
+ }
+ });
+ }
+ anim.play(getOpeningWindowAnimators(v, targetCompats, windowTargetBounds));
+ }
+
+ if (launcherClosing) {
+ anim.addListener(mForceInvisibleListener);
+ }
+
+ result.setAnimation(anim);
+ }
+ };
+
+ int duration = findTaskViewToLaunch(launcher, v, null) != null
+ ? RECENTS_LAUNCH_DURATION : APP_LAUNCH_DURATION;
+ int statusBarTransitionDelay = duration - STATUS_BAR_TRANSITION_DURATION;
+ return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
+ runner, duration, statusBarTransitionDelay));
+ }
+ return super.getActivityLaunchOptions(launcher, v);
+ }
+
+ /**
+ * Return the window bounds of the opening target.
+ * In multiwindow mode, we need to get the final size of the opening app window target to help
+ * figure out where the floating view should animate to.
+ */
+ private Rect getWindowTargetBounds(RemoteAnimationTargetCompat[] targets) {
+ Rect bounds = new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx);
+ if (mLauncher.isInMultiWindowModeCompat()) {
+ for (RemoteAnimationTargetCompat target : targets) {
+ if (target.mode == MODE_OPENING) {
+ bounds.set(target.sourceContainerBounds);
+ bounds.offsetTo(target.position.x, target.position.y);
+ return bounds;
+ }
+ }
+ }
+ return bounds;
+ }
+
+ public void setRemoteAnimationProvider(final RemoteAnimationProvider animationProvider,
+ CancellationSignal cancellationSignal) {
+ mRemoteAnimationProvider = animationProvider;
+ cancellationSignal.setOnCancelListener(() -> {
+ if (animationProvider == mRemoteAnimationProvider) {
+ mRemoteAnimationProvider = null;
+ }
+ });
+ }
+
+ /**
+ * Composes the animations for a launch from the recents list if possible.
+ */
+ private boolean composeRecentsLaunchAnimator(View v,
+ RemoteAnimationTargetCompat[] targets, AnimatorSet target) {
+ // Ensure recents is actually visible
+ if (!mLauncher.getStateManager().getState().overviewUi) {
+ return false;
+ }
+
+ RecentsView recentsView = mLauncher.getOverviewPanel();
+ boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
+ boolean skipLauncherChanges = !launcherClosing;
+ boolean isLaunchingFromQuickscrub =
+ recentsView.getQuickScrubController().isWaitingForTaskLaunch();
+
+ TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
+ if (taskView == null) {
+ return false;
+ }
+
+ int duration = isLaunchingFromQuickscrub
+ ? RECENTS_QUICKSCRUB_LAUNCH_DURATION
+ : RECENTS_LAUNCH_DURATION;
+
+ ClipAnimationHelper helper = new ClipAnimationHelper();
+ target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
+ .setDuration(duration));
+
+ Animator childStateAnimation = null;
+ // Found a visible recents task that matches the opening app, lets launch the app from there
+ Animator launcherAnim;
+ final AnimatorListenerAdapter windowAnimEndListener;
+ if (launcherClosing) {
+ launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper);
+ launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
+ launcherAnim.setDuration(duration);
+
+ // Make sure recents gets fixed up by resetting task alphas and scales, etc.
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.getStateManager().moveToRestState();
+ mLauncher.getStateManager().reapplyState();
+ }
+ };
+ } else {
+ AnimatorPlaybackController controller =
+ mLauncher.getStateManager().createAnimationToNewWorkspace(NORMAL, duration);
+ controller.dispatchOnStart();
+ childStateAnimation = controller.getTarget();
+ launcherAnim = controller.getAnimationPlayer().setDuration(duration);
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.getStateManager().goToState(NORMAL, false);
+ }
+ };
+ }
+ target.play(launcherAnim);
+
+ // Set the current animation first, before adding windowAnimEndListener. Setting current
+ // animation adds some listeners which need to be called before windowAnimEndListener
+ // (the ordering of listeners matter in this case).
+ mLauncher.getStateManager().setCurrentAnimation(target, childStateAnimation);
+ target.addListener(windowAnimEndListener);
+ return true;
+ }
+
+ /**
+ * Content is everything on screen except the background and the floating view (if any).
+ *
+ * @param isAppOpening True when this is called when an app is opening.
+ * False when this is called when an app is closing.
+ */
+ private Pair getLauncherContentAnimator(boolean isAppOpening) {
+ AnimatorSet launcherAnimator = new AnimatorSet();
+ Runnable endListener;
+
+ float[] alphas = isAppOpening
+ ? new float[] {1, 0}
+ : new float[] {0, 1};
+ float[] trans = isAppOpening
+ ? new float[] {0, mContentTransY}
+ : new float[] {-mContentTransY, 0};
+
+ if (mLauncher.isInState(ALL_APPS)) {
+ // All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
+ final View appsView = mLauncher.getAppsView();
+ final float startAlpha = appsView.getAlpha();
+ final float startY = appsView.getTranslationY();
+ appsView.setAlpha(alphas[0]);
+ appsView.setTranslationY(trans[0]);
+
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas);
+ alpha.setDuration(217);
+ alpha.setInterpolator(LINEAR);
+ appsView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ alpha.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ appsView.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ ObjectAnimator transY = ObjectAnimator.ofFloat(appsView, View.TRANSLATION_Y, trans);
+ transY.setInterpolator(AGGRESSIVE_EASE);
+ transY.setDuration(350);
+
+ launcherAnimator.play(alpha);
+ launcherAnimator.play(transY);
+
+ endListener = () -> {
+ appsView.setAlpha(startAlpha);
+ appsView.setTranslationY(startY);
+ appsView.setLayerType(View.LAYER_TYPE_NONE, null);
+ };
+ } else if (mLauncher.isInState(OVERVIEW)) {
+ AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
+ launcherAnimator.play(ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
+ allAppsController.getProgress(), ALL_APPS_PROGRESS_OFF_SCREEN));
+
+ View overview = mLauncher.getOverviewPanelContainer();
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(overview, View.ALPHA, alphas);
+ alpha.setDuration(217);
+ alpha.setInterpolator(LINEAR);
+ launcherAnimator.play(alpha);
+
+ ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans);
+ transY.setInterpolator(AGGRESSIVE_EASE);
+ transY.setDuration(350);
+ launcherAnimator.play(transY);
+
+ overview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ endListener = () -> {
+ overview.setLayerType(View.LAYER_TYPE_NONE, null);
+ overview.setAlpha(1f);
+ overview.setTranslationY(0f);
+ mLauncher.getStateManager().reapplyState();
+ };
+ } else {
+ mDragLayerAlpha.setValue(alphas[0]);
+ ObjectAnimator alpha =
+ ObjectAnimator.ofFloat(mDragLayerAlpha, MultiValueAlpha.VALUE, alphas);
+ alpha.setDuration(217);
+ alpha.setInterpolator(LINEAR);
+ launcherAnimator.play(alpha);
+
+ mDragLayer.setTranslationY(trans[0]);
+ ObjectAnimator transY = ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y, trans);
+ transY.setInterpolator(AGGRESSIVE_EASE);
+ transY.setDuration(350);
+ launcherAnimator.play(transY);
+
+ mDragLayer.getScrim().hideSysUiScrim(true);
+ // Pause page indicator animations as they lead to layer trashing.
+ mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+ mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ endListener = this::resetContentView;
+ }
+ return new Pair<>(launcherAnimator, endListener);
+ }
+
+ /**
+ * @return Animator that controls the icon used to launch the target.
+ */
+ private AnimatorSet getIconAnimator(View v, Rect windowTargetBounds) {
+ final boolean isBubbleTextView = v instanceof BubbleTextView;
+ mFloatingView = new View(mLauncher);
+ if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) {
+ // Create a copy of the app icon
+ mFloatingView.setBackground(
+ DrawableFactory.get(mLauncher).newIcon((ItemInfoWithIcon) v.getTag()));
+ }
+
+ // Position the floating view exactly on top of the original
+ Rect rect = new Rect();
+ final boolean fromDeepShortcutView = v.getParent() instanceof DeepShortcutView;
+ if (fromDeepShortcutView) {
+ // Deep shortcut views have their icon drawn in a separate view.
+ DeepShortcutView view = (DeepShortcutView) v.getParent();
+ mDragLayer.getDescendantRectRelativeToSelf(view.getIconView(), rect);
+ } else {
+ mDragLayer.getDescendantRectRelativeToSelf(v, rect);
+ }
+ int viewLocationLeft = rect.left;
+ int viewLocationTop = rect.top;
+
+ float startScale = 1f;
+ if (isBubbleTextView && !fromDeepShortcutView) {
+ BubbleTextView btv = (BubbleTextView) v;
+ btv.getIconBounds(rect);
+ Drawable dr = btv.getIcon();
+ if (dr instanceof FastBitmapDrawable) {
+ startScale = ((FastBitmapDrawable) dr).getAnimatedScale();
+ }
+ } else {
+ rect.set(0, 0, rect.width(), rect.height());
+ }
+ viewLocationLeft += rect.left;
+ viewLocationTop += rect.top;
+ int viewLocationStart = mIsRtl
+ ? windowTargetBounds.width() - rect.right
+ : viewLocationLeft;
+ LayoutParams lp = new LayoutParams(rect.width(), rect.height());
+ lp.ignoreInsets = true;
+ lp.setMarginStart(viewLocationStart);
+ lp.topMargin = viewLocationTop;
+ mFloatingView.setLayoutParams(lp);
+
+ // Set the properties here already to make sure they'are available when running the first
+ // animation frame.
+ mFloatingView.setLeft(viewLocationLeft);
+ mFloatingView.setTop(viewLocationTop);
+ mFloatingView.setRight(viewLocationLeft + rect.width());
+ mFloatingView.setBottom(viewLocationTop + rect.height());
+
+ // Swap the two views in place.
+ ((ViewGroup) mDragLayer.getParent()).addView(mFloatingView);
+ v.setVisibility(View.INVISIBLE);
+
+ AnimatorSet appIconAnimatorSet = new AnimatorSet();
+ int[] dragLayerBounds = new int[2];
+ mDragLayer.getLocationOnScreen(dragLayerBounds);
+
+ // Animate the app icon to the center of the window bounds in screen coordinates.
+ float centerX = windowTargetBounds.centerX() - dragLayerBounds[0];
+ float centerY = windowTargetBounds.centerY() - dragLayerBounds[1];
+
+ float xPosition = mIsRtl
+ ? windowTargetBounds.width() - lp.getMarginStart() - rect.width()
+ : lp.getMarginStart();
+ float dX = centerX - xPosition - (lp.width / 2);
+ float dY = centerY - lp.topMargin - (lp.height / 2);
+
+ ObjectAnimator x = ObjectAnimator.ofFloat(mFloatingView, View.TRANSLATION_X, 0f, dX);
+ ObjectAnimator y = ObjectAnimator.ofFloat(mFloatingView, View.TRANSLATION_Y, 0f, dY);
+
+ // Use upward animation for apps that are either on the bottom half of the screen, or are
+ // relatively close to the center.
+ boolean useUpwardAnimation = lp.topMargin > centerY
+ || Math.abs(dY) < mLauncher.getDeviceProfile().cellHeightPx;
+ if (useUpwardAnimation) {
+ x.setDuration(APP_LAUNCH_CURVED_DURATION);
+ y.setDuration(APP_LAUNCH_DURATION);
+ } else {
+ x.setDuration((long) (APP_LAUNCH_DOWN_DUR_SCALE_FACTOR * APP_LAUNCH_DURATION));
+ y.setDuration((long) (APP_LAUNCH_DOWN_DUR_SCALE_FACTOR * APP_LAUNCH_CURVED_DURATION));
+ }
+ x.setInterpolator(AGGRESSIVE_EASE);
+ y.setInterpolator(AGGRESSIVE_EASE);
+ appIconAnimatorSet.play(x);
+ appIconAnimatorSet.play(y);
+
+ // Scale the app icon to take up the entire screen. This simplifies the math when
+ // animating the app window position / scale.
+ float maxScaleX = windowTargetBounds.width() / (float) rect.width();
+ float maxScaleY = windowTargetBounds.height() / (float) rect.height();
+ float scale = Math.max(maxScaleX, maxScaleY);
+ ObjectAnimator scaleAnim = ObjectAnimator
+ .ofFloat(mFloatingView, SCALE_PROPERTY, startScale, scale);
+ scaleAnim.setDuration(APP_LAUNCH_DURATION)
+ .setInterpolator(Interpolators.EXAGGERATED_EASE);
+ appIconAnimatorSet.play(scaleAnim);
+
+ // Fade out the app icon.
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(mFloatingView, View.ALPHA, 1f, 0f);
+ if (useUpwardAnimation) {
+ alpha.setStartDelay(APP_LAUNCH_ALPHA_START_DELAY);
+ alpha.setDuration(APP_LAUNCH_ALPHA_DURATION);
+ } else {
+ alpha.setStartDelay((long) (APP_LAUNCH_DOWN_DUR_SCALE_FACTOR
+ * APP_LAUNCH_ALPHA_START_DELAY));
+ alpha.setDuration((long) (APP_LAUNCH_DOWN_DUR_SCALE_FACTOR * APP_LAUNCH_ALPHA_DURATION));
+ }
+ alpha.setInterpolator(LINEAR);
+ appIconAnimatorSet.play(alpha);
+
+ appIconAnimatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Reset launcher to normal state
+ v.setVisibility(View.VISIBLE);
+ ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
+ }
+ });
+ return appIconAnimatorSet;
+ }
+
+ /**
+ * @return Animator that controls the window of the opening targets.
+ */
+ private ValueAnimator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] targets,
+ Rect windowTargetBounds) {
+ Rect bounds = new Rect();
+ if (v.getParent() instanceof DeepShortcutView) {
+ // Deep shortcut views have their icon drawn in a separate view.
+ DeepShortcutView view = (DeepShortcutView) v.getParent();
+ mDragLayer.getDescendantRectRelativeToSelf(view.getIconView(), bounds);
+ } else if (v instanceof BubbleTextView) {
+ ((BubbleTextView) v).getIconBounds(bounds);
+ } else {
+ mDragLayer.getDescendantRectRelativeToSelf(v, bounds);
+ }
+ int[] floatingViewBounds = new int[2];
+
+ Rect crop = new Rect();
+ Matrix matrix = new Matrix();
+
+ ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
+ appAnimator.setDuration(APP_LAUNCH_DURATION);
+ appAnimator.addUpdateListener(new MultiValueUpdateListener() {
+ // Fade alpha for the app window.
+ FloatProp mAlpha = new FloatProp(0f, 1f, 0, 60, LINEAR);
+ boolean isFirstFrame = true;
+
+ @Override
+ public void onUpdate(float percent) {
+ final Surface surface = getSurface(mFloatingView);
+ final long frameNumber = surface != null ? getNextFrameNumber(surface) : -1;
+ if (frameNumber == -1) {
+ // Booo, not cool! Our surface got destroyed, so no reason to animate anything.
+ Log.w(TAG, "Failed to animate, surface got destroyed.");
+ return;
+ }
+ final float easePercent = AGGRESSIVE_EASE.getInterpolation(percent);
+
+ // Calculate app icon size.
+ float iconWidth = bounds.width() * mFloatingView.getScaleX();
+ float iconHeight = bounds.height() * mFloatingView.getScaleY();
+
+ // Scale the app window to match the icon size.
+ float scaleX = iconWidth / windowTargetBounds.width();
+ float scaleY = iconHeight / windowTargetBounds.height();
+ float scale = Math.min(1f, Math.min(scaleX, scaleY));
+ matrix.setScale(scale, scale);
+
+ // Position the scaled window on top of the icon
+ int windowWidth = windowTargetBounds.width();
+ int windowHeight = windowTargetBounds.height();
+ float scaledWindowWidth = windowWidth * scale;
+ float scaledWindowHeight = windowHeight * scale;
+
+ float offsetX = (scaledWindowWidth - iconWidth) / 2;
+ float offsetY = (scaledWindowHeight - iconHeight) / 2;
+ mFloatingView.getLocationOnScreen(floatingViewBounds);
+
+ float transX0 = floatingViewBounds[0] - offsetX;
+ float transY0 = floatingViewBounds[1] - offsetY;
+ matrix.postTranslate(transX0, transY0);
+
+ // Animate the window crop so that it starts off as a square, and then reveals
+ // horizontally.
+ float cropHeight = windowHeight * easePercent + windowWidth * (1 - easePercent);
+ float initialTop = (windowHeight - windowWidth) / 2f;
+ crop.left = 0;
+ crop.top = (int) (initialTop * (1 - easePercent));
+ crop.right = windowWidth;
+ crop.bottom = (int) (crop.top + cropHeight);
+
+ TransactionCompat t = new TransactionCompat();
+ if (isFirstFrame) {
+ RemoteAnimationProvider.prepareTargetsForFirstFrame(targets, t, MODE_OPENING);
+ isFirstFrame = false;
+ }
+ for (RemoteAnimationTargetCompat target : targets) {
+ if (target.mode == MODE_OPENING) {
+ t.setAlpha(target.leash, mAlpha.value);
+ t.setMatrix(target.leash, matrix);
+ t.setWindowCrop(target.leash, crop);
+ t.deferTransactionUntil(target.leash, surface, getNextFrameNumber(surface));
+ }
+ }
+ t.setEarlyWakeup();
+ t.apply();
+
+ matrix.reset();
+ }
+ });
+ return appAnimator;
+ }
+
+ /**
+ * Registers remote animations used when closing apps to home screen.
+ */
+ private void registerRemoteAnimations() {
+ // Unregister this
+ if (hasControlRemoteAppTransitionPermission()) {
+ RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
+ definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
+ WindowManagerWrapper.ACTIVITY_TYPE_STANDARD,
+ new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(),
+ CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
+
+ // TODO: Transition for unlock to home TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER
+ new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
+ }
+ }
+
+ private boolean launcherIsATargetWithMode(RemoteAnimationTargetCompat[] targets, int mode) {
+ return taskIsATargetWithMode(targets, mLauncher.getTaskId(), mode);
+ }
+
+ /**
+ * @return Runner that plays when user goes to Launcher
+ * ie. pressing home, swiping up from nav bar.
+ */
+ private RemoteAnimationRunnerCompat getWallpaperOpenRunner() {
+ return new LauncherAnimationRunner(mHandler, false /* startAtFrontOfQueue */) {
+ @Override
+ public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
+ AnimationResult result) {
+ if (!mLauncher.hasBeenResumed()) {
+ // If launcher is not resumed, wait until new async-frame after resume
+ mLauncher.setOnResumeCallback(() ->
+ postAsyncCallback(mHandler, () ->
+ onCreateAnimation(targetCompats, result)));
+ return;
+ }
+
+ AnimatorSet anim = null;
+ RemoteAnimationProvider provider = mRemoteAnimationProvider;
+ if (provider != null) {
+ anim = provider.createWindowAnimation(targetCompats);
+ }
+
+ if (anim == null) {
+ anim = new AnimatorSet();
+ anim.play(getClosingWindowAnimators(targetCompats));
+
+ // Normally, we run the launcher content animation when we are transitioning
+ // home, but if home is already visible, then we don't want to animate the
+ // contents of launcher unless we know that we are animating home as a result
+ // of the home button press with quickstep, which will result in launcher being
+ // started on touch down, prior to the animation home (and won't be in the
+ // targets list because it is already visible). In that case, we force
+ // invisibility on touch down, and only reset it after the animation to home
+ // is initialized.
+ if (launcherIsATargetWithMode(targetCompats, MODE_OPENING)
+ || mLauncher.isForceInvisible()) {
+ // Only register the content animation for cancellation when state changes
+ mLauncher.getStateManager().setCurrentAnimation(anim);
+ createLauncherResumeAnimation(anim);
+ }
+ }
+
+ mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
+ result.setAnimation(anim);
+ }
+ };
+ }
+
+ /**
+ * Animator that controls the transformations of the windows the targets that are closing.
+ */
+ private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] targets) {
+ Matrix matrix = new Matrix();
+ ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
+ int duration = CLOSING_TRANSITION_DURATION_MS;
+ closingAnimator.setDuration(duration);
+ closingAnimator.addUpdateListener(new MultiValueUpdateListener() {
+ FloatProp mDy = new FloatProp(0, mClosingWindowTransY, 0, duration, DEACCEL_1_7);
+ FloatProp mScale = new FloatProp(1f, 1f, 0, duration, DEACCEL_1_7);
+ FloatProp mAlpha = new FloatProp(1f, 0f, 25, 125, LINEAR);
+
+ boolean isFirstFrame = true;
+
+ @Override
+ public void onUpdate(float percent) {
+ TransactionCompat t = new TransactionCompat();
+ if (isFirstFrame) {
+ RemoteAnimationProvider.prepareTargetsForFirstFrame(targets, t, MODE_CLOSING);
+ isFirstFrame = false;
+ }
+ for (RemoteAnimationTargetCompat app : targets) {
+ if (app.mode == RemoteAnimationTargetCompat.MODE_CLOSING) {
+ t.setAlpha(app.leash, mAlpha.value);
+ matrix.setScale(mScale.value, mScale.value,
+ app.sourceContainerBounds.centerX(),
+ app.sourceContainerBounds.centerY());
+ matrix.postTranslate(0, mDy.value);
+ matrix.postTranslate(app.position.x, app.position.y);
+ t.setMatrix(app.leash, matrix);
+ }
+ }
+ t.setEarlyWakeup();
+ t.apply();
+
+ matrix.reset();
+ }
+ });
+
+ return closingAnimator;
+ }
+
+ /**
+ * Creates an animator that modifies Launcher as a result from {@link #getWallpaperOpenRunner}.
+ */
+ private void createLauncherResumeAnimation(AnimatorSet anim) {
+ if (mLauncher.isInState(LauncherState.ALL_APPS)) {
+ Pair contentAnimator =
+ getLauncherContentAnimator(false /* isAppOpening */);
+ contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
+ anim.play(contentAnimator.first);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ contentAnimator.second.run();
+ }
+ });
+ } else {
+ AnimatorSet workspaceAnimator = new AnimatorSet();
+
+ mDragLayer.setTranslationY(-mWorkspaceTransY);;
+ workspaceAnimator.play(ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y,
+ -mWorkspaceTransY, 0));
+
+ mDragLayerAlpha.setValue(0);
+ workspaceAnimator.play(ObjectAnimator.ofFloat(
+ mDragLayerAlpha, MultiValueAlpha.VALUE, 0, 1f));
+
+ workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
+ workspaceAnimator.setDuration(333);
+ workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7);
+
+ mDragLayer.getScrim().hideSysUiScrim(true);
+
+ // Pause page indicator animations as they lead to layer trashing.
+ mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+ mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ workspaceAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ resetContentView();
+ }
+ });
+ anim.play(workspaceAnimator);
+ }
+ }
+
+ private void resetContentView() {
+ mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
+ mDragLayerAlpha.setValue(1f);
+ mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null);
+ mDragLayer.setTranslationY(0f);
+ mDragLayer.getScrim().hideSysUiScrim(false);
+ }
+
+ private boolean hasControlRemoteAppTransitionPermission() {
+ return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
new file mode 100644
index 0000000000..08b6bfc6a0
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Handler;
+
+import com.android.launcher3.states.InternalStateHandler;
+import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
+import com.android.quickstep.OverviewCallbacks;
+import com.android.quickstep.util.RemoteAnimationProvider;
+
+import java.util.function.BiPredicate;
+
+@TargetApi(Build.VERSION_CODES.P)
+public class LauncherInitListener extends InternalStateHandler implements ActivityInitListener {
+
+ private final BiPredicate mOnInitListener;
+
+ private RemoteAnimationProvider mRemoteAnimationProvider;
+
+ public LauncherInitListener(BiPredicate onInitListener) {
+ mOnInitListener = onInitListener;
+ }
+
+ @Override
+ protected boolean init(Launcher launcher, boolean alreadyOnHome) {
+ if (mRemoteAnimationProvider != null) {
+ LauncherAppTransitionManagerImpl appTransitionManager =
+ (LauncherAppTransitionManagerImpl) launcher.getAppTransitionManager();
+
+ // Set a one-time animation provider. After the first call, this will get cleared.
+ // TODO: Probably also check the intended target id.
+ CancellationSignal cancellationSignal = new CancellationSignal();
+ appTransitionManager.setRemoteAnimationProvider((targets) -> {
+
+ // On the first call clear the reference.
+ cancellationSignal.cancel();
+ RemoteAnimationProvider provider = mRemoteAnimationProvider;
+ mRemoteAnimationProvider = null;
+
+ if (provider != null && launcher.getStateManager().getState().overviewUi) {
+ return provider.createWindowAnimation(targets);
+ }
+ return null;
+ }, cancellationSignal);
+ }
+ OverviewCallbacks.get(launcher).onInitOverviewTransition();
+ return mOnInitListener.test(launcher, alreadyOnHome);
+ }
+
+ @Override
+ public void register() {
+ initWhenReady();
+ }
+
+ @Override
+ public void unregister() {
+ mRemoteAnimationProvider = null;
+ clearReference();
+ }
+
+ @Override
+ public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
+ Context context, Handler handler, long duration) {
+ mRemoteAnimationProvider = animProvider;
+
+ register();
+
+ Bundle options = animProvider.toActivityOptions(handler, duration).toBundle();
+ context.startActivity(addToIntent(new Intent((intent))), options);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
new file mode 100644
index 0000000000..1eaa8bc92c
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -0,0 +1,89 @@
+/*
+ * 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.uioverrides;
+
+import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+
+/**
+ * Definition for AllApps state
+ */
+public class AllAppsState extends LauncherState {
+
+ private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY;
+
+ private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
+ @Override
+ public float getPageAlpha(int pageIndex) {
+ return 0;
+ }
+ };
+
+ public AllAppsState(int id) {
+ super(id, ContainerType.ALLAPPS, ALL_APPS_TRANSITION_MS, STATE_FLAGS);
+ }
+
+ @Override
+ public void onStateEnabled(Launcher launcher) {
+ AbstractFloatingView.closeAllOpenViews(launcher);
+ dispatchWindowStateChanged(launcher);
+ }
+
+ @Override
+ public String getDescription(Launcher launcher) {
+ AllAppsContainerView appsView = launcher.getAppsView();
+ return appsView.getDescription();
+ }
+
+ @Override
+ public float getVerticalProgress(Launcher launcher) {
+ return 0f;
+ }
+
+ @Override
+ public float[] getWorkspaceScaleAndTranslation(Launcher launcher) {
+ float[] scaleAndTranslation = LauncherState.OVERVIEW.getWorkspaceScaleAndTranslation(
+ launcher);
+ scaleAndTranslation[0] = 1;
+ return scaleAndTranslation;
+ }
+
+ @Override
+ public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
+ return PAGE_ALPHA_PROVIDER;
+ }
+
+ @Override
+ public int getVisibleElements(Launcher launcher) {
+ return ALL_APPS_HEADER | ALL_APPS_HEADER_EXTRA | ALL_APPS_CONTENT;
+ }
+
+ @Override
+ public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
+ return new float[] {0.9f, -0.2f};
+ }
+
+ @Override
+ public LauncherState getHistoryForState(LauncherState previousState) {
+ return previousState == OVERVIEW ? OVERVIEW : NORMAL;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java
new file mode 100644
index 0000000000..2e6dcc0e77
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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.uioverrides;
+
+import android.animation.ValueAnimator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.quickstep.OverviewInteractionState;
+
+public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler {
+
+ private static final String TAG = "BackButtonAlphaHandler";
+
+ private final Launcher mLauncher;
+ private final OverviewInteractionState mOverviewInteractionState;
+
+ public BackButtonAlphaHandler(Launcher launcher) {
+ mLauncher = launcher;
+ mOverviewInteractionState = OverviewInteractionState.getInstance(mLauncher);
+ }
+
+ @Override
+ public void setState(LauncherState state) {
+ UiFactory.onLauncherStateOrFocusChanged(mLauncher);
+ }
+
+ @Override
+ public void setStateWithAnimation(LauncherState toState,
+ AnimatorSetBuilder builder, LauncherStateManager.AnimationConfig config) {
+ if (!config.playNonAtomicComponent()) {
+ return;
+ }
+ float fromAlpha = mOverviewInteractionState.getBackButtonAlpha();
+ float toAlpha = toState.hideBackButton ? 0 : 1;
+ if (Float.compare(fromAlpha, toAlpha) != 0) {
+ ValueAnimator anim = ValueAnimator.ofFloat(fromAlpha, toAlpha);
+ anim.setDuration(config.duration);
+ anim.addUpdateListener(valueAnimator -> {
+ final float alpha = (float) valueAnimator.getAnimatedValue();
+ mOverviewInteractionState.setBackButtonAlpha(alpha, false);
+ });
+ builder.play(anim);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DisplayRotationListener.java b/quickstep/src/com/android/launcher3/uioverrides/DisplayRotationListener.java
new file mode 100644
index 0000000000..2d9a161475
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/DisplayRotationListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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.uioverrides;
+
+import android.content.Context;
+import android.os.Handler;
+
+import com.android.systemui.shared.system.RotationWatcher;
+
+/**
+ * Utility class for listening for rotation changes
+ */
+public class DisplayRotationListener extends RotationWatcher {
+
+ private final Runnable mCallback;
+ private Handler mHandler;
+
+ public DisplayRotationListener(Context context, Runnable callback) {
+ super(context);
+ mCallback = callback;
+ }
+
+ @Override
+ public void enable() {
+ if (mHandler == null) {
+ mHandler = new Handler();
+ }
+ super.enable();
+ }
+
+ @Override
+ protected void onRotationChanged(int i) {
+ mHandler.post(mCallback);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
new file mode 100644
index 0000000000..26453022f0
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 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.uioverrides;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.quickstep.QuickScrubController;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Extension of overview state used for QuickScrub
+ */
+public class FastOverviewState extends OverviewState {
+
+ private static final float MAX_PREVIEW_SCALE_UP = 1.3f;
+ /**
+ * Vertical transition of the task previews relative to the full container.
+ */
+ public static final float OVERVIEW_TRANSLATION_FACTOR = 0.4f;
+
+ private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
+ | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
+
+ public FastOverviewState(int id) {
+ super(id, QuickScrubController.QUICK_SCRUB_FROM_HOME_START_DURATION, STATE_FLAGS);
+ }
+
+ @Override
+ public void onStateTransitionEnd(Launcher launcher) {
+ super.onStateTransitionEnd(launcher);
+ RecentsView recentsView = launcher.getOverviewPanel();
+ recentsView.getQuickScrubController().onFinishedTransitionToQuickScrub();
+ }
+
+ @Override
+ public int getVisibleElements(Launcher launcher) {
+ return NONE;
+ }
+
+ @Override
+ public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
+ RecentsView recentsView = launcher.getOverviewPanel();
+ recentsView.getTaskSize(sTempRect);
+
+ return new float[] {getOverviewScale(launcher.getDeviceProfile(), sTempRect, launcher),
+ OVERVIEW_TRANSLATION_FACTOR};
+ }
+
+ public static float getOverviewScale(DeviceProfile dp, Rect taskRect, Context context) {
+ if (dp.isVerticalBarLayout()) {
+ return 1f;
+ }
+
+ Resources res = context.getResources();
+ float usedHeight = taskRect.height() + res.getDimension(R.dimen.task_thumbnail_top_margin);
+ float usedWidth = taskRect.width() + 2 * (res.getDimension(R.dimen.recents_page_spacing)
+ + res.getDimension(R.dimen.quickscrub_adjacent_visible_width));
+ return Math.min(Math.min(dp.availableHeightPx / usedHeight,
+ dp.availableWidthPx / usedWidth), MAX_PREVIEW_SCALE_UP);
+ }
+
+ @Override
+ public void onStateDisabled(Launcher launcher) {
+ super.onStateDisabled(launcher);
+ launcher.getOverviewPanel().getQuickScrubController().cancelActiveQuickscrub();
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
new file mode 100644
index 0000000000..6d1061990b
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
@@ -0,0 +1,79 @@
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.touch.AbstractStateChangeTouchController;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.quickstep.RecentsModel;
+
+/**
+ * Touch controller for handling edge swipes in landscape/seascape UI
+ */
+public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchController {
+
+ private static final String TAG = "LandscapeEdgeSwipeCtrl";
+
+ public LandscapeEdgeSwipeController(Launcher l) {
+ super(l, SwipeDetector.HORIZONTAL);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ if (mCurrentAnimation != null) {
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return false;
+ }
+ return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
+ }
+
+ @Override
+ protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
+ boolean draggingFromNav = mLauncher.getDeviceProfile().isSeascape() != isDragTowardPositive;
+ return draggingFromNav ? OVERVIEW : NORMAL;
+ }
+
+ @Override
+ protected int getLogContainerTypeForNormalState() {
+ return LauncherLogProto.ContainerType.NAVBAR;
+ }
+
+ @Override
+ protected float getShiftRange() {
+ return mLauncher.getDragLayer().getWidth();
+ }
+
+ @Override
+ protected float initCurrentAnimation(@AnimationComponents int animComponent) {
+ float range = getShiftRange();
+ long maxAccuracy = (long) (2 * range);
+ mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState,
+ maxAccuracy, animComponent);
+ return (mLauncher.getDeviceProfile().isSeascape() ? 2 : -2) / range;
+ }
+
+ @Override
+ protected int getDirectionForLog() {
+ return mLauncher.getDeviceProfile().isSeascape() ? Direction.RIGHT : Direction.LEFT;
+ }
+
+ @Override
+ protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
+ super.onSwipeInteractionCompleted(targetState, logAction);
+ if (mStartState == NORMAL && targetState == OVERVIEW) {
+ RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
new file mode 100644
index 0000000000..9169ffbc1e
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -0,0 +1,125 @@
+/*
+ * 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.uioverrides;
+
+import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
+
+import android.view.View;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.allapps.DiscoveryBounce;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Definition for overview state
+ */
+public class OverviewState extends LauncherState {
+
+ private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
+ | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
+
+ public OverviewState(int id) {
+ this(id, OVERVIEW_TRANSITION_MS, STATE_FLAGS);
+ }
+
+ protected OverviewState(int id, int transitionDuration, int stateFlags) {
+ super(id, ContainerType.TASKSWITCHER, transitionDuration, stateFlags);
+ }
+
+ @Override
+ public float[] getWorkspaceScaleAndTranslation(Launcher launcher) {
+ RecentsView recentsView = launcher.getOverviewPanel();
+ Workspace workspace = launcher.getWorkspace();
+ View workspacePage = workspace.getPageAt(workspace.getCurrentPage());
+ float workspacePageWidth = workspacePage != null && workspacePage.getWidth() != 0
+ ? workspacePage.getWidth() : launcher.getDeviceProfile().availableWidthPx;
+ recentsView.getTaskSize(sTempRect);
+ float scale = (float) sTempRect.width() / workspacePageWidth;
+ float parallaxFactor = 0.5f;
+ return new float[]{scale, 0, -getDefaultSwipeHeight(launcher) * parallaxFactor};
+ }
+
+ @Override
+ public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
+ return new float[] {1f, 0f};
+ }
+
+ @Override
+ public void onStateEnabled(Launcher launcher) {
+ RecentsView rv = launcher.getOverviewPanel();
+ rv.setOverviewStateEnabled(true);
+ AbstractFloatingView.closeAllOpenViews(launcher);
+ }
+
+ @Override
+ public void onStateDisabled(Launcher launcher) {
+ RecentsView rv = launcher.getOverviewPanel();
+ rv.setOverviewStateEnabled(false);
+ }
+
+ @Override
+ public void onStateTransitionEnd(Launcher launcher) {
+ launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE);
+ DiscoveryBounce.showForOverviewIfNeeded(launcher);
+ }
+
+ public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
+ return new PageAlphaProvider(DEACCEL_2) {
+ @Override
+ public float getPageAlpha(int pageIndex) {
+ return 0;
+ }
+ };
+ }
+
+ @Override
+ public int getVisibleElements(Launcher launcher) {
+ if (launcher.getDeviceProfile().isVerticalBarLayout()) {
+ return VERTICAL_SWIPE_INDICATOR;
+ } else {
+ return HOTSEAT_SEARCH_BOX | VERTICAL_SWIPE_INDICATOR |
+ (launcher.getAppsView().getFloatingHeaderView().hasVisibleContent()
+ ? ALL_APPS_HEADER_EXTRA : HOTSEAT_ICONS);
+ }
+ }
+
+ @Override
+ public float getWorkspaceScrimAlpha(Launcher launcher) {
+ return 0.5f;
+ }
+
+ @Override
+ public float getVerticalProgress(Launcher launcher) {
+ if ((getVisibleElements(launcher) & ALL_APPS_HEADER_EXTRA) == 0) {
+ // We have no all apps content, so we're still at the fully down progress.
+ return super.getVerticalProgress(launcher);
+ }
+ return 1 - (getDefaultSwipeHeight(launcher)
+ / launcher.getAllAppsController().getShiftRange());
+ }
+
+ public static float getDefaultSwipeHeight(Launcher launcher) {
+ DeviceProfile dp = launcher.getDeviceProfile();
+ return dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewToAllAppsTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewToAllAppsTouchController.java
new file mode 100644
index 0000000000..0f9b57f033
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewToAllAppsTouchController.java
@@ -0,0 +1,80 @@
+/*
+ * 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.uioverrides;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.quickstep.TouchInteractionService;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Touch controller from going from OVERVIEW to ALL_APPS.
+ *
+ * This is used in landscape mode. It is also used in portrait mode for the fallback recents.
+ */
+public class OverviewToAllAppsTouchController extends PortraitStatesTouchController {
+
+ public OverviewToAllAppsTouchController(Launcher l) {
+ super(l);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ if (mCurrentAnimation != null) {
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return false;
+ }
+ if (mLauncher.isInState(ALL_APPS)) {
+ // In all-apps only listen if the container cannot scroll itself
+ return mLauncher.getAppsView().shouldContainerScroll(ev);
+ } else if (mLauncher.isInState(NORMAL)) {
+ return true;
+ } else if (mLauncher.isInState(OVERVIEW)) {
+ RecentsView rv = mLauncher.getOverviewPanel();
+ return ev.getY() > (rv.getBottom() - rv.getPaddingBottom());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
+ if (fromState == ALL_APPS && !isDragTowardPositive) {
+ // Should swipe down go to OVERVIEW instead?
+ return TouchInteractionService.isConnected() ?
+ mLauncher.getStateManager().getLastState() : NORMAL;
+ } else if (isDragTowardPositive) {
+ return ALL_APPS;
+ }
+ return fromState;
+ }
+
+ @Override
+ protected int getLogContainerTypeForNormalState() {
+ return LauncherLogProto.ContainerType.WORKSPACE;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
new file mode 100644
index 0000000000..3fb7cd4802
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2018 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.uioverrides;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.view.MotionEvent;
+import android.view.animation.Interpolator;
+import android.view.animation.OvershootInterpolator;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.touch.AbstractStateChangeTouchController;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.RecentsModel;
+import com.android.quickstep.TouchInteractionService;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+
+/**
+ * Touch controller for handling various state transitions in portrait UI.
+ */
+public class PortraitStatesTouchController extends AbstractStateChangeTouchController {
+
+ private static final String TAG = "PortraitStatesTouchCtrl";
+
+ private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
+
+ // If true, we will finish the current animation instantly on second touch.
+ private boolean mFinishFastOnSecondTouch;
+
+
+ public PortraitStatesTouchController(Launcher l) {
+ super(l, SwipeDetector.VERTICAL);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ if (mCurrentAnimation != null) {
+ if (mFinishFastOnSecondTouch) {
+ // TODO: Animate to finish instead.
+ mCurrentAnimation.getAnimationPlayer().end();
+ }
+
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (mLauncher.isInState(ALL_APPS)) {
+ // In all-apps only listen if the container cannot scroll itself
+ if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
+ return false;
+ }
+ } else {
+ // For all other states, only listen if the event originated below the hotseat height
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
+ if (ev.getY() < (mLauncher.getDragLayer().getHeight() - hotseatHeight)) {
+ return false;
+ }
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
+ if (fromState == ALL_APPS && !isDragTowardPositive) {
+ // Should swipe down go to OVERVIEW instead?
+ return TouchInteractionService.isConnected() ?
+ mLauncher.getStateManager().getLastState() : NORMAL;
+ } else if (fromState == OVERVIEW) {
+ return isDragTowardPositive ? ALL_APPS : NORMAL;
+ } else if (fromState == NORMAL && isDragTowardPositive) {
+ return TouchInteractionService.isConnected() ? OVERVIEW : ALL_APPS;
+ }
+ return fromState;
+ }
+
+ @Override
+ protected int getLogContainerTypeForNormalState() {
+ return ContainerType.HOTSEAT;
+ }
+
+ private AnimatorSetBuilder getNormalToOverviewAnimation() {
+ mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR;
+
+ AnimatorSetBuilder builder = new AnimatorSetBuilder();
+ builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper);
+
+ return builder;
+ }
+
+ @Override
+ protected float initCurrentAnimation(@AnimationComponents int animComponents) {
+ float range = getShiftRange();
+ long maxAccuracy = (long) (2 * range);
+
+ float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
+ float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
+
+ float totalShift = endVerticalShift - startVerticalShift;
+
+ final AnimatorSetBuilder builder;
+
+ if (mFromState == NORMAL && mToState == OVERVIEW && totalShift != 0) {
+ builder = getNormalToOverviewAnimation();
+ } else {
+ builder = new AnimatorSetBuilder();
+ }
+
+ cancelPendingAnim();
+
+ RecentsView recentsView = mLauncher.getOverviewPanel();
+ TaskView taskView = (TaskView) recentsView.getChildAt(recentsView.getNextPage());
+ if (recentsView.shouldSwipeDownLaunchApp() && mFromState == OVERVIEW && mToState == NORMAL
+ && taskView != null) {
+ mPendingAnimation = recentsView.createTaskLauncherAnimation(taskView, maxAccuracy);
+ mPendingAnimation.anim.setInterpolator(Interpolators.ZOOM_IN);
+
+ Runnable onCancelRunnable = () -> {
+ cancelPendingAnim();
+ clearState();
+ };
+ mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy,
+ onCancelRunnable);
+ mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
+ } else {
+ mCurrentAnimation = mLauncher.getStateManager()
+ .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState,
+ animComponents);
+ }
+
+ if (totalShift == 0) {
+ totalShift = Math.signum(mFromState.ordinal - mToState.ordinal)
+ * OverviewState.getDefaultSwipeHeight(mLauncher);
+ }
+ return 1 / totalShift;
+ }
+
+ private void cancelPendingAnim() {
+ if (mPendingAnimation != null) {
+ mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation = null;
+ }
+ }
+
+ @Override
+ protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
+ LauncherState targetState, float velocity, boolean isFling) {
+ super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState,
+ velocity, isFling);
+ handleFirstSwipeToOverview(animator, expectedDuration, targetState, velocity, isFling);
+ }
+
+ private void handleFirstSwipeToOverview(final ValueAnimator animator,
+ final long expectedDuration, final LauncherState targetState, final float velocity,
+ final boolean isFling) {
+ if (mFromState == NORMAL && mToState == OVERVIEW && targetState == OVERVIEW) {
+ mFinishFastOnSecondTouch = true;
+ if (isFling && expectedDuration != 0) {
+ // Update all apps interpolator to add a bit of overshoot starting from currFraction
+ final float currFraction = mCurrentAnimation.getProgressFraction();
+ mAllAppsInterpolatorWrapper.baseInterpolator = Interpolators.clampToProgress(
+ new OvershootInterpolator(Math.min(Math.abs(velocity), 3f)), currFraction, 1);
+ animator.setDuration(Math.min(expectedDuration, ATOMIC_DURATION))
+ .setInterpolator(LINEAR);
+ }
+ } else {
+ mFinishFastOnSecondTouch = false;
+ }
+ }
+
+ @Override
+ protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
+ super.onSwipeInteractionCompleted(targetState, logAction);
+ if (mStartState == NORMAL && targetState == OVERVIEW) {
+ RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
+ }
+ }
+
+ private static class InterpolatorWrapper implements Interpolator {
+
+ public TimeInterpolator baseInterpolator = LINEAR;
+
+ @Override
+ public float getInterpolation(float v) {
+ return baseInterpolator.getInterpolation(v);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
new file mode 100644
index 0000000000..ea27eb25b9
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -0,0 +1,107 @@
+/*
+ * 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.uioverrides;
+
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
+import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
+import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
+import static com.android.quickstep.views.RecentsViewContainer.CONTENT_ALPHA;
+
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.quickstep.views.LauncherRecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
+
+@TargetApi(Build.VERSION_CODES.O)
+public class RecentsViewStateController implements StateHandler {
+
+ private final Launcher mLauncher;
+ private final LauncherRecentsView mRecentsView;
+ private final RecentsViewContainer mRecentsViewContainer;
+
+ public RecentsViewStateController(Launcher launcher) {
+ mLauncher = launcher;
+ mRecentsView = launcher.getOverviewPanel();
+ mRecentsViewContainer = launcher.getOverviewPanelContainer();
+ }
+
+ @Override
+ public void setState(LauncherState state) {
+ mRecentsViewContainer.setContentAlpha(state.overviewUi ? 1 : 0);
+ float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher);
+ SCALE_PROPERTY.set(mRecentsView, scaleTranslationYFactor[0]);
+ mRecentsView.setTranslationYFactor(scaleTranslationYFactor[1]);
+ if (state.overviewUi) {
+ mRecentsView.updateEmptyMessage();
+ mRecentsView.resetTaskVisuals();
+ }
+ }
+
+ @Override
+ public void setStateWithAnimation(final LauncherState toState,
+ AnimatorSetBuilder builder, AnimationConfig config) {
+ if (!config.playAtomicComponent()) {
+ // The entire recents animation is played atomically.
+ return;
+ }
+ PropertySetter setter = config.getPropertySetter(builder);
+ float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
+ Interpolator scaleAndTransYInterpolator = builder.getInterpolator(
+ ANIM_OVERVIEW_SCALE, LINEAR);
+ if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
+ scaleAndTransYInterpolator = Interpolators.clampToProgress(
+ QUICK_SCRUB_START_INTERPOLATOR, 0, QUICK_SCRUB_TRANSLATION_Y_FACTOR);
+ }
+ setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0],
+ scaleAndTransYInterpolator);
+ setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR, scaleTranslationYFactor[1],
+ scaleAndTransYInterpolator);
+ setter.setFloat(mRecentsViewContainer, CONTENT_ALPHA, toState.overviewUi ? 1 : 0,
+ builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
+
+ if (!toState.overviewUi) {
+ builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
+ }
+
+ if (toState.overviewUi) {
+ ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1);
+ updateAnim.addUpdateListener(valueAnimator -> {
+ // While animating into recents, update the visible task data as needed
+ mRecentsView.loadVisibleTaskData();
+ });
+ updateAnim.setDuration(config.duration);
+ builder.play(updateAnim);
+ mRecentsView.updateEmptyMessage();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
new file mode 100644
index 0000000000..a40573500f
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2018 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.uioverrides;
+
+import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
+import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.FlingBlockCheck;
+import com.android.launcher3.util.PendingAnimation;
+import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.OverviewInteractionState;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+
+/**
+ * Touch controller for handling task view card swipes
+ */
+public abstract class TaskViewTouchController
+ extends AnimatorListenerAdapter implements TouchController, SwipeDetector.Listener {
+
+ private static final String TAG = "OverviewSwipeController";
+
+ // Progress after which the transition is assumed to be a success in case user does not fling
+ private static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
+
+ protected final T mActivity;
+ private final SwipeDetector mDetector;
+ private final RecentsView mRecentsView;
+ private final int[] mTempCords = new int[2];
+
+ private PendingAnimation mPendingAnimation;
+ private AnimatorPlaybackController mCurrentAnimation;
+ private boolean mCurrentAnimationIsGoingUp;
+
+ private boolean mNoIntercept;
+
+ private float mDisplacementShift;
+ private float mProgressMultiplier;
+ private float mEndDisplacement;
+ private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
+
+ private TaskView mTaskBeingDragged;
+
+ public TaskViewTouchController(T activity) {
+ mActivity = activity;
+ mRecentsView = activity.getOverviewPanel();
+ mDetector = new SwipeDetector(activity, this, SwipeDetector.VERTICAL);
+ }
+
+ private boolean canInterceptTouch() {
+ if (mCurrentAnimation != null) {
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mActivity) != null) {
+ return false;
+ }
+ return isRecentsInteractive();
+ }
+
+ protected abstract boolean isRecentsInteractive();
+
+ protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
+ clearState();
+ }
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mNoIntercept = !canInterceptTouch();
+ if (mNoIntercept) {
+ return false;
+ }
+
+ // Now figure out which direction scroll events the controller will start
+ // calling the callbacks.
+ int directionsToDetectScroll = 0;
+ boolean ignoreSlopWhenSettling = false;
+ if (mCurrentAnimation != null) {
+ directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
+ ignoreSlopWhenSettling = true;
+ } else {
+ mTaskBeingDragged = null;
+
+ for (int i = 0; i < mRecentsView.getChildCount(); i++) {
+ TaskView view = mRecentsView.getPageAt(i);
+ if (mRecentsView.isTaskViewVisible(view) && mActivity.getDragLayer()
+ .isEventOverView(view, ev)) {
+ mTaskBeingDragged = view;
+ if (!OverviewInteractionState.getInstance(mActivity)
+ .isSwipeUpGestureEnabled()) {
+ // Don't allow swipe down to open if we don't support swipe up
+ // to enter overview.
+ directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
+ } else {
+ // The task can be dragged up to dismiss it,
+ // and down to open if it's the current page.
+ directionsToDetectScroll = i == mRecentsView.getCurrentPage()
+ ? SwipeDetector.DIRECTION_BOTH : SwipeDetector.DIRECTION_POSITIVE;
+ }
+ break;
+ }
+ }
+ if (mTaskBeingDragged == null) {
+ mNoIntercept = true;
+ return false;
+ }
+ }
+
+ mDetector.setDetectableScrollConditions(
+ directionsToDetectScroll, ignoreSlopWhenSettling);
+ }
+
+ if (mNoIntercept) {
+ return false;
+ }
+
+ onControllerTouchEvent(ev);
+ return mDetector.isDraggingOrSettling();
+ }
+
+ @Override
+ public boolean onControllerTouchEvent(MotionEvent ev) {
+ return mDetector.onTouchEvent(ev);
+ }
+
+ private void reInitAnimationController(boolean goingUp) {
+ if (mCurrentAnimation != null && mCurrentAnimationIsGoingUp == goingUp) {
+ // No need to init
+ return;
+ }
+ int scrollDirections = mDetector.getScrollDirections();
+ if (goingUp && ((scrollDirections & SwipeDetector.DIRECTION_POSITIVE) == 0)
+ || !goingUp && ((scrollDirections & SwipeDetector.DIRECTION_NEGATIVE) == 0)) {
+ // Trying to re-init in an unsupported direction.
+ return;
+ }
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.setPlayFraction(0);
+ }
+ if (mPendingAnimation != null) {
+ mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation = null;
+ }
+
+ mCurrentAnimationIsGoingUp = goingUp;
+ BaseDragLayer dl = mActivity.getDragLayer();
+ long maxDuration = (long) (2 * dl.getHeight());
+
+ if (goingUp) {
+ mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
+ true /* animateTaskView */, true /* removeTask */, maxDuration);
+
+ mEndDisplacement = -mTaskBeingDragged.getHeight();
+ } else {
+ mPendingAnimation = mRecentsView.createTaskLauncherAnimation(
+ mTaskBeingDragged, maxDuration);
+ mPendingAnimation.anim.setInterpolator(Interpolators.ZOOM_IN);
+
+ mTempCords[1] = mTaskBeingDragged.getHeight();
+ dl.getDescendantCoordRelativeToSelf(mTaskBeingDragged, mTempCords);
+ mEndDisplacement = dl.getHeight() - mTempCords[1];
+ }
+
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.setOnCancelRunnable(null);
+ }
+ mCurrentAnimation = AnimatorPlaybackController
+ .wrap(mPendingAnimation.anim, maxDuration, this::clearState);
+ onUserControlledAnimationCreated(mCurrentAnimation);
+ mCurrentAnimation.getTarget().addListener(this);
+ mCurrentAnimation.dispatchOnStart();
+ mProgressMultiplier = 1 / mEndDisplacement;
+ }
+
+ @Override
+ public void onDragStart(boolean start) {
+ if (mCurrentAnimation == null) {
+ reInitAnimationController(mDetector.wasInitialTouchPositive());
+ mDisplacementShift = 0;
+ } else {
+ mDisplacementShift = mCurrentAnimation.getProgressFraction() / mProgressMultiplier;
+ mCurrentAnimation.pause();
+ }
+ mFlingBlockCheck.unblockFling();
+ }
+
+ @Override
+ public boolean onDrag(float displacement, float velocity) {
+ float totalDisplacement = displacement + mDisplacementShift;
+ boolean isGoingUp =
+ totalDisplacement == 0 ? mCurrentAnimationIsGoingUp : totalDisplacement < 0;
+ if (isGoingUp != mCurrentAnimationIsGoingUp) {
+ reInitAnimationController(isGoingUp);
+ mFlingBlockCheck.blockFling();
+ } else {
+ mFlingBlockCheck.onEvent();
+ }
+ mCurrentAnimation.setPlayFraction(totalDisplacement * mProgressMultiplier);
+ return true;
+ }
+
+ @Override
+ public void onDragEnd(float velocity, boolean fling) {
+ final boolean goingToEnd;
+ final int logAction;
+ boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
+ if (blockedFling) {
+ fling = false;
+ }
+ if (fling) {
+ logAction = Touch.FLING;
+ boolean goingUp = velocity < 0;
+ goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
+ } else {
+ logAction = Touch.SWIPE;
+ goingToEnd = mCurrentAnimation.getProgressFraction() > SUCCESS_TRANSITION_PROGRESS;
+ }
+
+ float progress = mCurrentAnimation.getProgressFraction();
+ long animationDuration = SwipeDetector.calculateDuration(
+ velocity, goingToEnd ? (1 - progress) : progress);
+ if (blockedFling && !goingToEnd) {
+ animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity);
+ }
+
+ float nextFrameProgress = Utilities.boundToRange(
+ progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f);
+
+ mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd, logAction));
+
+ ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
+ anim.setFloatValues(nextFrameProgress, goingToEnd ? 1f : 0f);
+ anim.setDuration(animationDuration);
+ anim.setInterpolator(scrollInterpolatorForVelocity(velocity));
+ anim.start();
+ }
+
+ private void onCurrentAnimationEnd(boolean wasSuccess, int logAction) {
+ if (mPendingAnimation != null) {
+ mPendingAnimation.finish(wasSuccess, logAction);
+ mPendingAnimation = null;
+ }
+ clearState();
+ }
+
+ private void clearState() {
+ mDetector.finishedScrolling();
+ mDetector.setDetectableScrollConditions(0, false);
+ mTaskBeingDragged = null;
+ mCurrentAnimation = null;
+ if (mPendingAnimation != null) {
+ mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation = null;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
new file mode 100644
index 0000000000..dd5dcbeaf8
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -0,0 +1,255 @@
+/*
+ * 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.uioverrides;
+
+import static android.view.View.VISIBLE;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_SEEN;
+import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.util.Base64;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppTransitionManagerImpl;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.util.TouchController;
+import com.android.quickstep.OverviewInteractionState;
+import com.android.quickstep.RecentsModel;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteFadeOutAnimationListener;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.ActivityCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.util.zip.Deflater;
+
+public class UiFactory {
+
+ public static TouchController[] createTouchControllers(Launcher launcher) {
+ boolean swipeUpEnabled = OverviewInteractionState.getInstance(launcher)
+ .isSwipeUpGestureEnabled();
+ if (!swipeUpEnabled) {
+ return new TouchController[] {
+ launcher.getDragController(),
+ new OverviewToAllAppsTouchController(launcher),
+ new LauncherTaskViewController(launcher)};
+ }
+ if (launcher.getDeviceProfile().isVerticalBarLayout()) {
+ return new TouchController[] {
+ launcher.getDragController(),
+ new OverviewToAllAppsTouchController(launcher),
+ new LandscapeEdgeSwipeController(launcher),
+ new LauncherTaskViewController(launcher)};
+ } else {
+ return new TouchController[] {
+ launcher.getDragController(),
+ new PortraitStatesTouchController(launcher),
+ new LauncherTaskViewController(launcher)};
+ }
+ }
+
+ public static void setOnTouchControllersChangedListener(Context context, Runnable listener) {
+ OverviewInteractionState.getInstance(context).setOnSwipeUpSettingChangedListener(listener);
+ }
+
+ public static StateHandler[] getStateHandler(Launcher launcher) {
+ return new StateHandler[] {launcher.getAllAppsController(), launcher.getWorkspace(),
+ new RecentsViewStateController(launcher), new BackButtonAlphaHandler(launcher)};
+ }
+
+ /**
+ * Sets the back button visibility based on the current state/window focus.
+ */
+ public static void onLauncherStateOrFocusChanged(Launcher launcher) {
+ boolean shouldBackButtonBeHidden = launcher != null
+ && launcher.getStateManager().getState().hideBackButton
+ && launcher.hasWindowFocus();
+ if (shouldBackButtonBeHidden) {
+ // Show the back button if there is a floating view visible.
+ shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(launcher,
+ TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
+ }
+ OverviewInteractionState.getInstance(launcher)
+ .setBackButtonAlpha(shouldBackButtonBeHidden ? 0 : 1, true /* animate */);
+ }
+
+ public static void resetOverview(Launcher launcher) {
+ RecentsView recents = launcher.getOverviewPanel();
+ recents.reset();
+ }
+
+ public static void onCreate(Launcher launcher) {
+ if (!launcher.getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false)) {
+ launcher.getStateManager().addStateListener(new LauncherStateManager.StateListener() {
+ @Override
+ public void onStateSetImmediately(LauncherState state) {
+ }
+
+ @Override
+ public void onStateTransitionStart(LauncherState toState) {
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ boolean swipeUpEnabled = OverviewInteractionState.getInstance(launcher)
+ .isSwipeUpGestureEnabled();
+ LauncherState prevState = launcher.getStateManager().getLastState();
+
+ if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
+ && finalState == ALL_APPS && prevState == NORMAL))) {
+ launcher.getSharedPrefs().edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
+ launcher.getStateManager().removeStateListener(this);
+ }
+ }
+ });
+ }
+
+ if (!launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false)) {
+ launcher.getStateManager().addStateListener(new LauncherStateManager.StateListener() {
+ @Override
+ public void onStateSetImmediately(LauncherState state) {
+ }
+
+ @Override
+ public void onStateTransitionStart(LauncherState toState) {
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ LauncherState prevState = launcher.getStateManager().getLastState();
+
+ if (finalState == ALL_APPS && prevState == OVERVIEW) {
+ launcher.getSharedPrefs().edit().putBoolean(SHELF_BOUNCE_SEEN, true).apply();
+ launcher.getStateManager().removeStateListener(this);
+ }
+ }
+ });
+ }
+ }
+
+ public static void onStart(Context context) {
+ RecentsModel model = RecentsModel.getInstance(context);
+ if (model != null) {
+ model.onStart();
+ }
+ }
+
+ public static void onLauncherStateOrResumeChanged(Launcher launcher) {
+ LauncherState state = launcher.getStateManager().getState();
+ DeviceProfile profile = launcher.getDeviceProfile();
+ WindowManagerWrapper.getInstance().setShelfHeight(
+ state != ALL_APPS && launcher.isUserActive() && !profile.isVerticalBarLayout(),
+ profile.hotseatBarSizePx);
+
+ if (state == NORMAL) {
+ launcher.getOverviewPanel().setSwipeDownShouldLaunchApp(false);
+ }
+ }
+
+ public static void onTrimMemory(Context context, int level) {
+ RecentsModel model = RecentsModel.getInstance(context);
+ if (model != null) {
+ model.onTrimMemory(level);
+ }
+ }
+
+ public static void useFadeOutAnimationForLauncherStart(Launcher launcher,
+ CancellationSignal cancellationSignal) {
+ LauncherAppTransitionManagerImpl appTransitionManager =
+ (LauncherAppTransitionManagerImpl) launcher.getAppTransitionManager();
+ appTransitionManager.setRemoteAnimationProvider((targets) -> {
+
+ // On the first call clear the reference.
+ cancellationSignal.cancel();
+
+ ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
+ fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(targets));
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(fadeAnimation);
+ return anim;
+ }, cancellationSignal);
+ }
+
+ public static boolean dumpActivity(Activity activity, PrintWriter writer) {
+ if (!Utilities.IS_DEBUG_DEVICE) {
+ return false;
+ }
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ if (!(new ActivityCompat(activity).encodeViewHierarchy(out))) {
+ return false;
+ }
+
+ Deflater deflater = new Deflater();
+ deflater.setInput(out.toByteArray());
+ deflater.finish();
+
+ out.reset();
+ byte[] buffer = new byte[1024];
+ while (!deflater.finished()) {
+ int count = deflater.deflate(buffer); // returns the generated code... index
+ out.write(buffer, 0, count);
+ }
+
+ writer.println("--encoded-view-dump-v0--");
+ writer.println(Base64.encodeToString(
+ out.toByteArray(), Base64.NO_WRAP | Base64.NO_PADDING));
+ return true;
+ }
+
+ public static void prepareToShowOverview(Launcher launcher) {
+ RecentsView overview = launcher.getOverviewPanel();
+ if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
+ SCALE_PROPERTY.set(overview, 1.33f);
+ }
+ }
+
+ private static class LauncherTaskViewController extends TaskViewTouchController {
+
+ public LauncherTaskViewController(Launcher activity) {
+ super(activity);
+ }
+
+ @Override
+ protected boolean isRecentsInteractive() {
+ return mActivity.isInState(OVERVIEW);
+ }
+
+ @Override
+ protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
+ mActivity.getStateManager().setCurrentUserControlledAnimation(animController);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/WallpaperColorInfo.java b/quickstep/src/com/android/launcher3/uioverrides/WallpaperColorInfo.java
new file mode 100644
index 0000000000..8218517dcc
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/WallpaperColorInfo.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2018 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.uioverrides;
+
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+
+import android.annotation.TargetApi;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.app.WallpaperManager.OnColorsChangedListener;
+import android.content.Context;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+
+import com.android.systemui.shared.system.TonalCompat;
+import com.android.systemui.shared.system.TonalCompat.ExtractionInfo;
+
+import java.util.ArrayList;
+
+@TargetApi(Build.VERSION_CODES.P)
+public class WallpaperColorInfo implements OnColorsChangedListener {
+
+ private static final Object sInstanceLock = new Object();
+ private static WallpaperColorInfo sInstance;
+
+ public static WallpaperColorInfo getInstance(Context context) {
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ sInstance = new WallpaperColorInfo(context.getApplicationContext());
+ }
+ return sInstance;
+ }
+ }
+
+ private final ArrayList mListeners = new ArrayList<>();
+ private final WallpaperManager mWallpaperManager;
+ private final TonalCompat mTonalCompat;
+
+ private ExtractionInfo mExtractionInfo;
+
+ private OnChangeListener[] mTempListeners = new OnChangeListener[0];
+
+ private WallpaperColorInfo(Context context) {
+ mWallpaperManager = context.getSystemService(WallpaperManager.class);
+ mTonalCompat = new TonalCompat(context);
+
+ mWallpaperManager.addOnColorsChangedListener(this, new Handler(Looper.getMainLooper()));
+ update(mWallpaperManager.getWallpaperColors(FLAG_SYSTEM));
+ }
+
+ public int getMainColor() {
+ return mExtractionInfo.mainColor;
+ }
+
+ public int getSecondaryColor() {
+ return mExtractionInfo.secondaryColor;
+ }
+
+ public boolean isDark() {
+ return mExtractionInfo.supportsDarkTheme;
+ }
+
+ public boolean supportsDarkText() {
+ return mExtractionInfo.supportsDarkText;
+ }
+
+ @Override
+ public void onColorsChanged(WallpaperColors colors, int which) {
+ if ((which & FLAG_SYSTEM) != 0) {
+ update(colors);
+ notifyChange();
+ }
+ }
+
+ private void update(WallpaperColors wallpaperColors) {
+ mExtractionInfo = mTonalCompat.extractDarkColors(wallpaperColors);
+ }
+
+ public void addOnChangeListener(OnChangeListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void removeOnChangeListener(OnChangeListener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void notifyChange() {
+ // Create a new array to avoid concurrent modification when the activity destroys itself.
+ mTempListeners = mListeners.toArray(mTempListeners);
+ for (OnChangeListener listener : mTempListeners) {
+ if (listener != null) {
+ listener.onExtractedColorsChanged(this);
+ }
+ }
+ }
+
+ public interface OnChangeListener {
+ void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
new file mode 100644
index 0000000000..52a6dd5fe5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
+import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
+import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
+
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
+import android.view.View;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherInitListener;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.allapps.DiscoveryBounce;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.uioverrides.FastOverviewState;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.TouchConsumer.InteractionType;
+import com.android.quickstep.util.LayoutUtils;
+import com.android.quickstep.util.TransformedRect;
+import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.views.LauncherLayoutListener;
+import com.android.quickstep.views.LauncherRecentsView;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+
+import java.util.Objects;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+
+/**
+ * Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public interface ActivityControlHelper {
+
+ LayoutListener createLayoutListener(T activity);
+
+ /**
+ * Updates the UI to indicate quick interaction.
+ */
+ void onQuickInteractionStart(T activity, @Nullable RunningTaskInfo taskInfo,
+ boolean activityVisible);
+
+ float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
+ Context context);
+
+ void executeOnWindowAvailable(T activity, Runnable action);
+
+ void onTransitionCancelled(T activity, boolean activityVisible);
+
+ int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
+ @InteractionType int interactionType, TransformedRect outRect);
+
+ void onSwipeUpComplete(T activity);
+
+ AnimationFactory prepareRecentsUI(T activity, boolean activityVisible,
+ Consumer callback);
+
+ ActivityInitListener createActivityInitListener(BiPredicate onInitListener);
+
+ @Nullable
+ T getCreatedActivity();
+
+ @UiThread
+ @Nullable
+ RecentsView getVisibleRecentsView();
+
+ @UiThread
+ boolean switchToRecentsIfVisible(boolean fromRecentsButton);
+
+ Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target);
+
+ boolean shouldMinimizeSplitScreen();
+
+ /**
+ * @return {@code true} if recents activity should be started immediately on touchDown,
+ * {@code false} if it should deferred until some threshold is crossed.
+ */
+ boolean deferStartingActivity(int downHitTarget);
+
+ boolean supportsLongSwipe(T activity);
+
+ AlphaProperty getAlphaProperty(T activity);
+
+ /**
+ * Must return a non-null controller is supportsLongSwipe was true.
+ */
+ LongSwipeHelper getLongSwipeController(T activity, RemoteAnimationTargetSet targetSet);
+
+ /**
+ * Used for containerType in {@link com.android.launcher3.logging.UserEventDispatcher}
+ */
+ int getContainerType();
+
+ class LauncherActivityControllerHelper implements ActivityControlHelper {
+
+ @Override
+ public LayoutListener createLayoutListener(Launcher activity) {
+ return new LauncherLayoutListener(activity);
+ }
+
+ @Override
+ public void onQuickInteractionStart(Launcher activity, RunningTaskInfo taskInfo,
+ boolean activityVisible) {
+ LauncherState fromState = activity.getStateManager().getState();
+ activity.getStateManager().goToState(FAST_OVERVIEW, activityVisible);
+
+ QuickScrubController controller = activity.getOverviewPanel()
+ .getQuickScrubController();
+ controller.onQuickScrubStart(activityVisible && !fromState.overviewUi, this);
+ }
+
+ @Override
+ public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
+ Context context) {
+ // The padding calculations are exactly same as that of RecentsView.setInsets
+ int topMargin = context.getResources()
+ .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+ int paddingTop = targetRect.rect.top - topMargin - dp.getInsets().top;
+ int paddingBottom = dp.availableHeightPx + dp.getInsets().top - targetRect.rect.bottom;
+
+ return FastOverviewState.OVERVIEW_TRANSLATION_FACTOR * (paddingBottom - paddingTop);
+ }
+
+ @Override
+ public void executeOnWindowAvailable(Launcher activity, Runnable action) {
+ activity.getWorkspace().runOnOverlayHidden(action);
+ }
+
+ @Override
+ public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
+ @InteractionType int interactionType, TransformedRect outRect) {
+ LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect);
+ if (interactionType == INTERACTION_QUICK_SCRUB) {
+ outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context);
+ }
+ if (dp.isVerticalBarLayout()) {
+ Rect targetInsets = dp.getInsets();
+ int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
+ return dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
+ } else {
+ return dp.heightPx - outRect.rect.bottom;
+ }
+ }
+
+ @Override
+ public void onTransitionCancelled(Launcher activity, boolean activityVisible) {
+ LauncherState startState = activity.getStateManager().getRestState();
+ activity.getStateManager().goToState(startState, activityVisible);
+ }
+
+ @Override
+ public void onSwipeUpComplete(Launcher activity) {
+ // Re apply state in case we did something funky during the transition.
+ activity.getStateManager().reapplyState();
+ DiscoveryBounce.showForOverviewIfNeeded(activity);
+ }
+
+ @Override
+ public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible,
+ Consumer callback) {
+ final LauncherState startState = activity.getStateManager().getState();
+
+ LauncherState resetState = startState;
+ if (startState.disableRestore) {
+ resetState = activity.getStateManager().getRestState();
+ }
+ activity.getStateManager().setRestState(resetState);
+
+ if (!activityVisible) {
+ // Since the launcher is not visible, we can safely reset the scroll position.
+ // This ensures then the next swipe up to all-apps starts from scroll 0.
+ activity.getAppsView().reset(false /* animate */);
+ activity.getStateManager().goToState(OVERVIEW, false);
+
+ // Optimization, hide the all apps view to prevent layout while initializing
+ activity.getAppsView().getContentView().setVisibility(View.GONE);
+ }
+
+ return new AnimationFactory() {
+ @Override
+ public void createActivityController(long transitionLength,
+ @InteractionType int interactionType) {
+ createActivityControllerInternal(activity, activityVisible, startState,
+ transitionLength, interactionType, callback);
+ }
+
+ @Override
+ public void onTransitionCancelled() {
+ activity.getStateManager().goToState(startState, false /* animate */);
+ }
+ };
+ }
+
+ private void createActivityControllerInternal(Launcher activity, boolean wasVisible,
+ LauncherState startState, long transitionLength,
+ @InteractionType int interactionType,
+ Consumer callback) {
+ LauncherState endState = interactionType == INTERACTION_QUICK_SCRUB
+ ? FAST_OVERVIEW : OVERVIEW;
+ if (wasVisible) {
+ DeviceProfile dp = activity.getDeviceProfile();
+ long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
+ activity.getStateManager().goToState(startState, false);
+ callback.accept(activity.getStateManager()
+ .createAnimationToNewWorkspace(endState, accuracy));
+ return;
+ }
+
+ if (activity.getDeviceProfile().isVerticalBarLayout()) {
+ return;
+ }
+
+ AllAppsTransitionController controller = activity.getAllAppsController();
+ AnimatorSet anim = new AnimatorSet();
+
+ float scrollRange = Math.max(controller.getShiftRange(), 1);
+ float progressDelta = (transitionLength / scrollRange);
+
+ float endProgress = endState.getVerticalProgress(activity);
+ float startProgress = endProgress + progressDelta;
+ ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(
+ controller, ALL_APPS_PROGRESS, startProgress, endProgress);
+ shiftAnim.setInterpolator(LINEAR);
+ anim.play(shiftAnim);
+
+ anim.setDuration(transitionLength * 2);
+ activity.getStateManager().setCurrentAnimation(anim);
+ callback.accept(AnimatorPlaybackController.wrap(anim, transitionLength * 2));
+ }
+
+ @Override
+ public ActivityInitListener createActivityInitListener(
+ BiPredicate onInitListener) {
+ return new LauncherInitListener(onInitListener);
+ }
+
+ @Nullable
+ @Override
+ public Launcher getCreatedActivity() {
+ LauncherAppState app = LauncherAppState.getInstanceNoCreate();
+ if (app == null) {
+ return null;
+ }
+ return (Launcher) app.getModel().getCallback();
+ }
+
+ @Nullable
+ @UiThread
+ private Launcher getVisibleLaucher() {
+ Launcher launcher = getCreatedActivity();
+ return (launcher != null) && launcher.isStarted() && launcher.hasWindowFocus() ?
+ launcher : null;
+ }
+
+ @Nullable
+ @Override
+ public RecentsView getVisibleRecentsView() {
+ Launcher launcher = getVisibleLaucher();
+ return launcher != null && launcher.getStateManager().getState().overviewUi
+ ? launcher.getOverviewPanel() : null;
+ }
+
+ @Override
+ public boolean switchToRecentsIfVisible(boolean fromRecentsButton) {
+ Launcher launcher = getVisibleLaucher();
+ if (launcher != null) {
+ if (fromRecentsButton) {
+ launcher.getUserEventDispatcher().logActionCommand(
+ LauncherLogProto.Action.Command.RECENTS_BUTTON,
+ getContainerType(),
+ LauncherLogProto.ContainerType.TASKSWITCHER);
+ }
+ launcher.getStateManager().goToState(OVERVIEW);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean deferStartingActivity(int downHitTarget) {
+ return downHitTarget == HIT_TARGET_BACK || downHitTarget == HIT_TARGET_ROTATION;
+ }
+
+ @Override
+ public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target) {
+ return homeBounds;
+ }
+
+ @Override
+ public boolean shouldMinimizeSplitScreen() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsLongSwipe(Launcher activity) {
+ return !activity.getDeviceProfile().isVerticalBarLayout();
+ }
+
+ @Override
+ public LongSwipeHelper getLongSwipeController(Launcher activity,
+ RemoteAnimationTargetSet targetSet) {
+ if (activity.getDeviceProfile().isVerticalBarLayout()) {
+ return null;
+ }
+ return new LongSwipeHelper(activity, targetSet);
+ }
+
+ @Override
+ public AlphaProperty getAlphaProperty(Launcher activity) {
+ return activity.getDragLayer().getAlphaProperty(DragLayer.ALPHA_INDEX_SWIPE_UP);
+ }
+
+ @Override
+ public int getContainerType() {
+ final Launcher launcher = getVisibleLaucher();
+ return launcher != null ? launcher.getStateManager().getState().containerType
+ : LauncherLogProto.ContainerType.APP;
+ }
+ }
+
+ class FallbackActivityControllerHelper implements ActivityControlHelper {
+
+ private final ComponentName mHomeComponent;
+ private final Handler mUiHandler = new Handler(Looper.getMainLooper());
+
+ public FallbackActivityControllerHelper(ComponentName homeComponent) {
+ mHomeComponent = homeComponent;
+ }
+
+ @Override
+ public void onQuickInteractionStart(RecentsActivity activity, RunningTaskInfo taskInfo,
+ boolean activityVisible) {
+ QuickScrubController controller = activity.getOverviewPanel()
+ .getQuickScrubController();
+
+ // TODO: match user is as well
+ boolean startingFromHome = !activityVisible &&
+ (taskInfo == null || Objects.equals(taskInfo.topActivity, mHomeComponent));
+ controller.onQuickScrubStart(startingFromHome, this);
+ if (activityVisible) {
+ mUiHandler.postDelayed(controller::onFinishedTransitionToQuickScrub,
+ OVERVIEW_TRANSITION_MS);
+ }
+ }
+
+ @Override
+ public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
+ Context context) {
+ return 0;
+ }
+
+ @Override
+ public void executeOnWindowAvailable(RecentsActivity activity, Runnable action) {
+ action.run();
+ }
+
+ @Override
+ public void onTransitionCancelled(RecentsActivity activity, boolean activityVisible) {
+ // TODO:
+ }
+
+ @Override
+ public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
+ @InteractionType int interactionType, TransformedRect outRect) {
+ LayoutUtils.calculateFallbackTaskSize(context, dp, outRect.rect);
+ if (dp.isVerticalBarLayout()) {
+ Rect targetInsets = dp.getInsets();
+ int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
+ return dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
+ } else {
+ return dp.heightPx - outRect.rect.bottom;
+ }
+ }
+
+ @Override
+ public void onSwipeUpComplete(RecentsActivity activity) {
+ // TODO:
+ }
+
+ @Override
+ public AnimationFactory prepareRecentsUI(RecentsActivity activity, boolean activityVisible,
+ Consumer callback) {
+ if (activityVisible) {
+ return (transitionLength, interactionType) -> { };
+ }
+
+ RecentsViewContainer rv = activity.getOverviewPanelContainer();
+ rv.setContentAlpha(0);
+
+ return new AnimationFactory() {
+
+ boolean isAnimatingHome = false;
+
+ @Override
+ public void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) {
+ isAnimatingHome = targets != null && targets.isAnimatingHome();
+ if (!isAnimatingHome) {
+ rv.setContentAlpha(1);
+ }
+ createActivityController(getSwipeUpDestinationAndLength(
+ activity.getDeviceProfile(), activity, INTERACTION_NORMAL,
+ new TransformedRect()), INTERACTION_NORMAL);
+ }
+
+ @Override
+ public void createActivityController(long transitionLength, int interactionType) {
+ if (!isAnimatingHome) {
+ return;
+ }
+
+ ObjectAnimator anim = ObjectAnimator
+ .ofFloat(rv, RecentsViewContainer.CONTENT_ALPHA, 0, 1);
+ anim.setDuration(transitionLength).setInterpolator(LINEAR);
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.play(anim);
+ callback.accept(AnimatorPlaybackController.wrap(animatorSet, transitionLength));
+ }
+ };
+ }
+
+ @Override
+ public LayoutListener createLayoutListener(RecentsActivity activity) {
+ // We do not change anything as part of layout changes in fallback activity. Return a
+ // default layout listener.
+ return new LayoutListener() {
+ @Override
+ public void open() { }
+
+ @Override
+ public void setHandler(WindowTransformSwipeHandler handler) { }
+
+ @Override
+ public void finish() { }
+ };
+ }
+
+ @Override
+ public ActivityInitListener createActivityInitListener(
+ BiPredicate onInitListener) {
+ return new RecentsActivityTracker(onInitListener);
+ }
+
+ @Nullable
+ @Override
+ public RecentsActivity getCreatedActivity() {
+ return RecentsActivityTracker.getCurrentActivity();
+ }
+
+ @Nullable
+ @Override
+ public RecentsView getVisibleRecentsView() {
+ RecentsActivity activity = getCreatedActivity();
+ if (activity != null && activity.hasWindowFocus()) {
+ return activity.getOverviewPanel();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean switchToRecentsIfVisible(boolean fromRecentsButton) {
+ return false;
+ }
+
+ @Override
+ public boolean deferStartingActivity(int downHitTarget) {
+ // Always defer starting the activity when using fallback
+ return true;
+ }
+
+ @Override
+ public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target) {
+ // TODO: Remove this once b/77875376 is fixed
+ return target.sourceContainerBounds;
+ }
+
+ @Override
+ public boolean shouldMinimizeSplitScreen() {
+ // TODO: Remove this once b/77875376 is fixed
+ return false;
+ }
+
+ @Override
+ public boolean supportsLongSwipe(RecentsActivity activity) {
+ return false;
+ }
+
+ @Override
+ public LongSwipeHelper getLongSwipeController(RecentsActivity activity,
+ RemoteAnimationTargetSet targetSet) {
+ return null;
+ }
+
+ @Override
+ public AlphaProperty getAlphaProperty(RecentsActivity activity) {
+ return activity.getDragLayer().getAlphaProperty(0);
+ }
+
+ @Override
+ public int getContainerType() {
+ return LauncherLogProto.ContainerType.SIDELOADED_LAUNCHER;
+ }
+ }
+
+ interface LayoutListener {
+
+ void open();
+
+ void setHandler(WindowTransformSwipeHandler handler);
+
+ void finish();
+ }
+
+ interface ActivityInitListener {
+
+ void register();
+
+ void unregister();
+
+ void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
+ Context context, Handler handler, long duration);
+ }
+
+ interface AnimationFactory {
+
+ default void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) { }
+
+ void createActivityController(long transitionLength, @InteractionType int interactionType);
+
+ default void onTransitionCancelled() { }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/quickstep/src/com/android/quickstep/AnimatedFloat.java
new file mode 100644
index 0000000000..84dfdbd1dd
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/AnimatedFloat.java
@@ -0,0 +1,89 @@
+/*
+ * 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.quickstep;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.util.FloatProperty;
+
+/**
+ * A mutable float which allows animating the value
+ */
+public class AnimatedFloat {
+
+ public static FloatProperty VALUE = new FloatProperty("value") {
+ @Override
+ public void setValue(AnimatedFloat obj, float v) {
+ obj.updateValue(v);
+ }
+
+ @Override
+ public Float get(AnimatedFloat obj) {
+ return obj.value;
+ }
+ };
+
+ private final Runnable mUpdateCallback;
+ private ObjectAnimator mValueAnimator;
+
+ public float value;
+
+ public AnimatedFloat(Runnable updateCallback) {
+ mUpdateCallback = updateCallback;
+ }
+
+ public ObjectAnimator animateToValue(float start, float end) {
+ cancelAnimation();
+ mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, start, end);
+ mValueAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if (mValueAnimator == animator) {
+ mValueAnimator = null;
+ }
+ }
+ });
+ return mValueAnimator;
+ }
+
+ /**
+ * Changes the value and calls the callback.
+ * Note that the value can be directly accessed as well to avoid notifying the callback.
+ */
+ public void updateValue(float v) {
+ if (Float.compare(v, value) != 0) {
+ value = v;
+ mUpdateCallback.run();
+ }
+ }
+
+ public void cancelAnimation() {
+ if (mValueAnimator != null) {
+ mValueAnimator.cancel();
+ }
+ }
+
+ public void finishAnimation() {
+ if (mValueAnimator != null && mValueAnimator.isRunning()) {
+ mValueAnimator.end();
+ }
+ }
+
+ public ObjectAnimator getCurrentAnimation() {
+ return mValueAnimator;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
new file mode 100644
index 0000000000..8e83bd0792
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.view.Choreographer;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+
+/**
+ * A TouchConsumer which defers all events on the UIThread until the consumer is created.
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class DeferredTouchConsumer implements TouchConsumer {
+
+ private final VelocityTracker mVelocityTracker;
+ private final DeferredTouchProvider mTouchProvider;
+
+ private MotionEventQueue mMyQueue;
+ private TouchConsumer mTarget;
+
+ public DeferredTouchConsumer(DeferredTouchProvider touchProvider) {
+ mVelocityTracker = VelocityTracker.obtain();
+ mTouchProvider = touchProvider;
+ }
+
+ @Override
+ public void accept(MotionEvent event) {
+ mTarget.accept(event);
+ }
+
+ @Override
+ public void reset() {
+ mTarget.reset();
+ }
+
+ @Override
+ public void updateTouchTracking(int interactionType) {
+ mTarget.updateTouchTracking(interactionType);
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ mTarget.onQuickScrubEnd();
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ mTarget.onQuickScrubProgress(progress);
+ }
+
+ @Override
+ public void onQuickStep(MotionEvent ev) {
+ mTarget.onQuickStep(ev);
+ }
+
+ @Override
+ public void onCommand(int command) {
+ mTarget.onCommand(command);
+ }
+
+ @Override
+ public void preProcessMotionEvent(MotionEvent ev) {
+ mVelocityTracker.addMovement(ev);
+ }
+
+ @Override
+ public Choreographer getIntrimChoreographer(MotionEventQueue queue) {
+ mMyQueue = queue;
+ return null;
+ }
+
+ @Override
+ public void deferInit() {
+ mTarget = mTouchProvider.createTouchConsumer(mVelocityTracker);
+ mTarget.getIntrimChoreographer(mMyQueue);
+ }
+
+ @Override
+ public boolean forceToLauncherConsumer() {
+ return mTarget.forceToLauncherConsumer();
+ }
+
+ @Override
+ public boolean deferNextEventToMainThread() {
+ // If our target is still null, defer the next target as well
+ TouchConsumer target = mTarget;
+ return target == null ? true : target.deferNextEventToMainThread();
+ }
+
+ @Override
+ public void onShowOverviewFromAltTab() {
+ mTarget.onShowOverviewFromAltTab();
+ }
+
+ public interface DeferredTouchProvider {
+
+ TouchConsumer createTouchConsumer(VelocityTracker tracker);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java b/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java
new file mode 100644
index 0000000000..12757c0f79
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.InstantAppInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.util.InstantAppResolver;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of InstantAppResolver using platform APIs
+ */
+@SuppressWarnings("unused")
+public class InstantAppResolverImpl extends InstantAppResolver {
+
+ private static final String TAG = "InstantAppResolverImpl";
+ public static final String COMPONENT_CLASS_MARKER = "@instantapp";
+
+ private final PackageManager mPM;
+
+ public InstantAppResolverImpl(Context context)
+ throws NoSuchMethodException, ClassNotFoundException {
+ mPM = context.getPackageManager();
+ }
+
+ @Override
+ public boolean isInstantApp(ApplicationInfo info) {
+ return info.isInstantApp();
+ }
+
+ @Override
+ public boolean isInstantApp(AppInfo info) {
+ ComponentName cn = info.getTargetComponent();
+ return cn != null && cn.getClassName().equals(COMPONENT_CLASS_MARKER);
+ }
+
+ @Override
+ public List getInstantApps() {
+ try {
+ List result = new ArrayList<>();
+ for (InstantAppInfo iai : mPM.getInstantApps()) {
+ ApplicationInfo info = iai.getApplicationInfo();
+ if (info != null) {
+ result.add(info);
+ }
+ }
+ return result;
+ } catch (SecurityException se) {
+ Log.w(TAG, "getInstantApps failed. Launcher may not be the default home app.", se);
+ } catch (Exception e) {
+ Log.e(TAG, "Error calling API: getInstantApps", e);
+ }
+ return super.getInstantApps();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java b/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java
new file mode 100644
index 0000000000..f5e1f6ec56
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.annotation.TargetApi;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.pm.ResolveInfo;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.os.Build;
+import android.provider.SearchIndexablesContract.XmlResource;
+import android.provider.SearchIndexablesProvider;
+import android.util.Xml;
+
+import com.android.launcher3.R;
+import com.android.launcher3.graphics.IconShapeOverride;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
+import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS;
+import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS;
+
+@TargetApi(Build.VERSION_CODES.O)
+public class LauncherSearchIndexablesProvider extends SearchIndexablesProvider {
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor queryXmlResources(String[] strings) {
+ MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
+ ResolveInfo settingsActivity = getContext().getPackageManager().resolveActivity(
+ new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+ .setPackage(getContext().getPackageName()), 0);
+ cursor.newRow()
+ .add(XmlResource.COLUMN_XML_RESID, R.xml.indexable_launcher_prefs)
+ .add(XmlResource.COLUMN_INTENT_ACTION, Intent.ACTION_APPLICATION_PREFERENCES)
+ .add(XmlResource.COLUMN_INTENT_TARGET_PACKAGE, getContext().getPackageName())
+ .add(XmlResource.COLUMN_INTENT_TARGET_CLASS, settingsActivity.activityInfo.name);
+ return cursor;
+ }
+
+ @Override
+ public Cursor queryRawData(String[] projection) {
+ return new MatrixCursor(INDEXABLES_RAW_COLUMNS);
+ }
+
+ @Override
+ public Cursor queryNonIndexableKeys(String[] projection) {
+ MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
+ if (!getContext().getSystemService(LauncherApps.class).hasShortcutHostPermission()) {
+ // We are not the current launcher. Hide all preferences
+ try (XmlResourceParser parser = getContext().getResources()
+ .getXml(R.xml.indexable_launcher_prefs)) {
+ final int depth = parser.getDepth();
+ final int[] attrs = new int[] { android.R.attr.key };
+ int type;
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+ if (type == XmlPullParser.START_TAG) {
+ TypedArray a = getContext().obtainStyledAttributes(
+ Xml.asAttributeSet(parser), attrs);
+ cursor.addRow(new String[] {a.getString(0)});
+ a.recycle();
+ }
+ }
+ } catch (IOException |XmlPullParserException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (!IconShapeOverride.isSupported(getContext())) {
+ cursor.addRow(new String[] {IconShapeOverride.KEY_PREFERENCE});
+ }
+ return cursor;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
new file mode 100644
index 0000000000..fbcde8bba2
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.launcher3.LauncherAnimUtils.MIN_PROGRESS_TO_ALL_APPS;
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION;
+import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
+import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
+
+import android.animation.ValueAnimator;
+import android.view.Surface;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.allapps.DiscoveryBounce;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.FlingBlockCheck;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+
+/**
+ * Utility class to handle long swipe from an app.
+ * This assumes the presence of Launcher activity as long swipe is not supported on the
+ * fallback activity.
+ */
+public class LongSwipeHelper {
+
+ private static final float SWIPE_DURATION_MULTIPLIER =
+ Math.min(1 / MIN_PROGRESS_TO_ALL_APPS, 1 / (1 - MIN_PROGRESS_TO_ALL_APPS));
+
+ private final Launcher mLauncher;
+ private final RemoteAnimationTargetSet mTargetSet;
+
+ private float mMaxSwipeDistance = 1;
+ private AnimatorPlaybackController mAnimator;
+ private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
+
+ LongSwipeHelper(Launcher launcher, RemoteAnimationTargetSet targetSet) {
+ mLauncher = launcher;
+ mTargetSet = targetSet;
+ init();
+ }
+
+ private void init() {
+ setTargetAlpha(0, true);
+ mFlingBlockCheck.blockFling();
+
+ // Init animations
+ AllAppsTransitionController controller = mLauncher.getAllAppsController();
+ // TODO: Scale it down so that we can reach all-apps in screen space
+ mMaxSwipeDistance = Math.max(1, controller.getProgress() * controller.getShiftRange());
+ mAnimator = mLauncher.getStateManager()
+ .createAnimationToNewWorkspace(ALL_APPS, Math.round(2 * mMaxSwipeDistance));
+ mAnimator.dispatchOnStart();
+ }
+
+ public void onMove(float displacement) {
+ mAnimator.setPlayFraction(displacement / mMaxSwipeDistance);
+ mFlingBlockCheck.onEvent();
+ }
+
+ public void destroy() {
+ // TODO: We can probably also hide the task view
+ setTargetAlpha(1, false);
+
+ mLauncher.getStateManager().goToState(OVERVIEW, false);
+ }
+
+ public void end(float velocity, boolean isFling, Runnable callback) {
+ long duration = MAX_SWIPE_DURATION;
+
+ final float currentFraction = mAnimator.getProgressFraction();
+ final boolean toAllApps;
+ float endProgress;
+
+ boolean blockedFling = isFling && mFlingBlockCheck.isBlocked();
+ if (blockedFling) {
+ isFling = false;
+ }
+
+ if (!isFling) {
+ toAllApps = currentFraction > MIN_PROGRESS_TO_ALL_APPS;
+ endProgress = toAllApps ? 1 : 0;
+
+ long expectedDuration = Math.abs(Math.round((endProgress - currentFraction)
+ * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
+ duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
+ } else {
+ toAllApps = velocity < 0;
+ endProgress = toAllApps ? 1 : 0;
+
+ float minFlingVelocity = mLauncher.getResources()
+ .getDimension(R.dimen.quickstep_fling_min_velocity);
+ if (Math.abs(velocity) > minFlingVelocity && mMaxSwipeDistance > 0) {
+ float distanceToTravel = (endProgress - currentFraction) * mMaxSwipeDistance;
+
+ // we want the page's snap velocity to approximately match the velocity at
+ // which the user flings, so we scale the duration by a value near to the
+ // derivative of the scroll interpolator at zero, ie. 2.
+ long baseDuration = Math.round(1000 * Math.abs(distanceToTravel / velocity));
+ duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration);
+ }
+ }
+
+ if (blockedFling && !toAllApps) {
+ duration *= LauncherAnimUtils.blockedFlingDurationFactor(0);
+ }
+ final boolean finalIsFling = isFling;
+ mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, finalIsFling, callback));
+ ValueAnimator animator = mAnimator.getAnimationPlayer();
+ animator.setDuration(duration).setInterpolator(DEACCEL);
+ animator.setFloatValues(currentFraction, endProgress);
+ animator.start();
+ }
+
+ private void setTargetAlpha(float alpha, boolean defer) {
+ final Surface surface = getSurface(mLauncher.getDragLayer());
+ final long frameNumber = defer && surface != null ? getNextFrameNumber(surface) : -1;
+ if (defer) {
+ if (frameNumber == -1) {
+ defer = false;
+ } else {
+ mLauncher.getDragLayer().invalidate();
+ }
+ }
+
+ TransactionCompat transaction = new TransactionCompat();
+ for (RemoteAnimationTargetCompat app : mTargetSet.apps) {
+ if (!(app.isNotInRecents
+ || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME)) {
+ transaction.setAlpha(app.leash, alpha);
+ if (defer) {
+ transaction.deferTransactionUntil(app.leash, surface, frameNumber);
+ }
+ }
+ }
+ transaction.setEarlyWakeup();
+ transaction.apply();
+ }
+
+ private void onSwipeAnimationComplete(boolean toAllApps, boolean isFling, Runnable callback) {
+ mLauncher.getStateManager().goToState(toAllApps ? ALL_APPS : OVERVIEW, false);
+ if (!toAllApps) {
+ DiscoveryBounce.showForOverviewIfNeeded(mLauncher);
+ mLauncher.getOverviewPanel().setSwipeDownShouldLaunchApp(true);
+ }
+
+ mLauncher.getUserEventDispatcher().logStateChangeAction(
+ isFling ? Touch.FLING : Touch.SWIPE, Direction.UP,
+ ContainerType.NAVBAR, ContainerType.APP,
+ toAllApps ? ContainerType.ALLAPPS : ContainerType.TASKSWITCHER,
+ 0);
+
+ callback.run();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
new file mode 100644
index 0000000000..f73be6cba9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -0,0 +1,248 @@
+/*
+ * 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.quickstep;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_MASK;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.MotionEvent;
+
+import com.android.systemui.shared.system.ChoreographerCompat;
+
+import java.util.ArrayList;
+
+/**
+ * Helper class for batching input events
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class MotionEventQueue {
+
+ private static final String TAG = "MotionEventQueue";
+
+ private static final int ACTION_VIRTUAL = ACTION_MASK - 1;
+
+ private static final int ACTION_QUICK_SCRUB_START =
+ ACTION_VIRTUAL | (1 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_QUICK_SCRUB_PROGRESS =
+ ACTION_VIRTUAL | (2 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_QUICK_SCRUB_END =
+ ACTION_VIRTUAL | (3 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_RESET =
+ ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_DEFER_INIT =
+ ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_SHOW_OVERVIEW_FROM_ALT_TAB =
+ ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_QUICK_STEP =
+ ACTION_VIRTUAL | (7 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_COMMAND =
+ ACTION_VIRTUAL | (8 << ACTION_POINTER_INDEX_SHIFT);
+
+ private final EventArray mEmptyArray = new EventArray();
+ private final Object mExecutionLock = new Object();
+
+ // We use two arrays and swap the current index when one array is being consumed
+ private final EventArray[] mArrays = new EventArray[] {new EventArray(), new EventArray()};
+ private int mCurrentIndex = 0;
+
+ private final Runnable mMainFrameCallback = this::frameCallbackForMainChoreographer;
+ private final Runnable mInterimFrameCallback = this::frameCallbackForInterimChoreographer;
+
+ private final Choreographer mMainChoreographer;
+
+ private final TouchConsumer mConsumer;
+
+ private Choreographer mInterimChoreographer;
+ private Choreographer mCurrentChoreographer;
+
+ private Runnable mCurrentRunnable;
+
+ public MotionEventQueue(Choreographer choreographer, TouchConsumer consumer) {
+ mMainChoreographer = choreographer;
+ mConsumer = consumer;
+ mCurrentChoreographer = mMainChoreographer;
+ mCurrentRunnable = mMainFrameCallback;
+
+ setInterimChoreographer(consumer.getIntrimChoreographer(this));
+ }
+
+ public void setInterimChoreographer(Choreographer choreographer) {
+ synchronized (mExecutionLock) {
+ synchronized (mArrays) {
+ setInterimChoreographerLocked(choreographer);
+ ChoreographerCompat.postInputFrame(mCurrentChoreographer, mCurrentRunnable);
+ }
+ }
+ }
+
+ private void setInterimChoreographerLocked(Choreographer choreographer) {
+ mInterimChoreographer = choreographer;
+ if (choreographer == null) {
+ mCurrentChoreographer = mMainChoreographer;
+ mCurrentRunnable = mMainFrameCallback;
+ } else {
+ mCurrentChoreographer = mInterimChoreographer;
+ mCurrentRunnable = mInterimFrameCallback;
+ }
+ }
+
+ public void queue(MotionEvent event) {
+ mConsumer.preProcessMotionEvent(event);
+ queueNoPreProcess(event);
+ }
+
+ private void queueNoPreProcess(MotionEvent event) {
+ synchronized (mArrays) {
+ EventArray array = mArrays[mCurrentIndex];
+ if (array.isEmpty()) {
+ ChoreographerCompat.postInputFrame(mCurrentChoreographer, mCurrentRunnable);
+ }
+
+ int eventAction = event.getAction();
+ if (eventAction == ACTION_MOVE && array.lastEventAction == ACTION_MOVE) {
+ // Replace and recycle the last event
+ array.set(array.size() - 1, event).recycle();
+ } else {
+ array.add(event);
+ array.lastEventAction = eventAction;
+ }
+ }
+ }
+
+ private void frameCallbackForMainChoreographer() {
+ runFor(mMainChoreographer);
+ }
+
+ private void frameCallbackForInterimChoreographer() {
+ runFor(mInterimChoreographer);
+ }
+
+ private void runFor(Choreographer caller) {
+ synchronized (mExecutionLock) {
+ EventArray array = swapAndGetCurrentArray(caller);
+ int size = array.size();
+ for (int i = 0; i < size; i++) {
+ MotionEvent event = array.get(i);
+ if (event.getActionMasked() == ACTION_VIRTUAL) {
+ switch (event.getAction()) {
+ case ACTION_QUICK_SCRUB_START:
+ mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
+ break;
+ case ACTION_QUICK_SCRUB_PROGRESS:
+ mConsumer.onQuickScrubProgress(event.getX());
+ break;
+ case ACTION_QUICK_SCRUB_END:
+ mConsumer.onQuickScrubEnd();
+ break;
+ case ACTION_RESET:
+ mConsumer.reset();
+ break;
+ case ACTION_DEFER_INIT:
+ mConsumer.deferInit();
+ break;
+ case ACTION_SHOW_OVERVIEW_FROM_ALT_TAB:
+ mConsumer.onShowOverviewFromAltTab();
+ mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
+ break;
+ case ACTION_QUICK_STEP:
+ mConsumer.onQuickStep(event);
+ break;
+ case ACTION_COMMAND:
+ mConsumer.onCommand(event.getSource());
+ break;
+ default:
+ Log.e(TAG, "Invalid virtual event: " + event.getAction());
+ }
+ } else {
+ mConsumer.accept(event);
+ }
+ event.recycle();
+ }
+ array.clear();
+ array.lastEventAction = ACTION_CANCEL;
+ }
+ }
+
+ private EventArray swapAndGetCurrentArray(Choreographer caller) {
+ synchronized (mArrays) {
+ if (caller != mCurrentChoreographer) {
+ return mEmptyArray;
+ }
+ EventArray current = mArrays[mCurrentIndex];
+ mCurrentIndex = mCurrentIndex ^ 1;
+ return current;
+ }
+ }
+
+ private void queueVirtualAction(int action, float progress) {
+ queueNoPreProcess(MotionEvent.obtain(0, 0, action, progress, 0, 0));
+ }
+
+ public void onQuickScrubStart() {
+ queueVirtualAction(ACTION_QUICK_SCRUB_START, 0);
+ }
+
+ public void onOverviewShownFromAltTab() {
+ queueVirtualAction(ACTION_SHOW_OVERVIEW_FROM_ALT_TAB, 0);
+ }
+
+ public void onQuickScrubProgress(float progress) {
+ queueVirtualAction(ACTION_QUICK_SCRUB_PROGRESS, progress);
+ }
+
+ public void onQuickScrubEnd() {
+ queueVirtualAction(ACTION_QUICK_SCRUB_END, 0);
+ }
+
+ public void onQuickStep(MotionEvent event) {
+ event.setAction(ACTION_QUICK_STEP);
+ queueNoPreProcess(event);
+ }
+
+ public void reset() {
+ queueVirtualAction(ACTION_RESET, 0);
+ }
+
+ public void deferInit() {
+ queueVirtualAction(ACTION_DEFER_INIT, 0);
+ }
+
+ public void onCommand(int command) {
+ MotionEvent ev = MotionEvent.obtain(0, 0, ACTION_COMMAND, 0, 0, 0);
+ ev.setSource(command);
+ queueNoPreProcess(ev);
+ }
+
+ public TouchConsumer getConsumer() {
+ return mConsumer;
+ }
+
+ private static class EventArray extends ArrayList {
+
+ public int lastEventAction = ACTION_CANCEL;
+
+ public EventArray() {
+ super(4);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
new file mode 100644
index 0000000000..bda3d06aac
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -0,0 +1,66 @@
+/*
+ * 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.quickstep;
+
+import android.util.SparseArray;
+
+/**
+ * Utility class to help manage multiple callbacks based on different states.
+ */
+public class MultiStateCallback {
+
+ private final SparseArray mCallbacks = new SparseArray<>();
+
+ private int mState = 0;
+
+ /**
+ * Adds the provided state flags to the global state and executes any callbacks as a result.
+ * @param stateFlag
+ */
+ public void setState(int stateFlag) {
+ mState = mState | stateFlag;
+
+ int count = mCallbacks.size();
+ for (int i = 0; i < count; i++) {
+ int state = mCallbacks.keyAt(i);
+
+ if ((mState & state) == state) {
+ Runnable callback = mCallbacks.valueAt(i);
+ if (callback != null) {
+ // Set the callback to null, so that it does not run again.
+ mCallbacks.setValueAt(i, null);
+ callback.run();
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the callbacks to be run when the provided states are enabled.
+ * The callback is only run once.
+ */
+ public void addCallback(int stateMask, Runnable callback) {
+ mCallbacks.put(stateMask, callback);
+ }
+
+ public int getState() {
+ return mState;
+ }
+
+ public boolean hasStates(int stateMask) {
+ return (mState & stateMask) == stateMask;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
new file mode 100644
index 0000000000..f875bb786e
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.annotation.TargetApi;
+import android.app.ActivityManager.TaskDescription;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.UserHandle;
+import android.util.LruCache;
+import android.util.SparseArray;
+
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.graphics.BitmapInfo;
+import com.android.launcher3.graphics.DrawableFactory;
+import com.android.launcher3.graphics.LauncherIcons;
+import com.android.systemui.shared.recents.model.IconLoader;
+import com.android.systemui.shared.recents.model.TaskKeyLruCache;
+
+/**
+ * Extension of {@link IconLoader} with icon normalization support
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class NormalizedIconLoader extends IconLoader {
+
+ private final SparseArray mDefaultIcons = new SparseArray<>();
+ private final DrawableFactory mDrawableFactory;
+ private LauncherIcons mLauncherIcons;
+
+ public NormalizedIconLoader(Context context, TaskKeyLruCache iconCache,
+ LruCache activityInfoCache) {
+ super(context, iconCache, activityInfoCache);
+ mDrawableFactory = DrawableFactory.get(context);
+ }
+
+ @Override
+ public Drawable getDefaultIcon(int userId) {
+ synchronized (mDefaultIcons) {
+ BitmapInfo info = mDefaultIcons.get(userId);
+ if (info == null) {
+ info = getBitmapInfo(Resources.getSystem()
+ .getDrawable(android.R.drawable.sym_def_app_icon), userId, 0, false);
+ mDefaultIcons.put(userId, info);
+ }
+
+ return new FastBitmapDrawable(info);
+ }
+ }
+
+ @Override
+ protected Drawable createBadgedDrawable(Drawable drawable, int userId, TaskDescription desc) {
+ return new FastBitmapDrawable(getBitmapInfo(drawable, userId, desc.getPrimaryColor(),
+ false));
+ }
+
+ private synchronized BitmapInfo getBitmapInfo(Drawable drawable, int userId,
+ int primaryColor, boolean isInstantApp) {
+ if (mLauncherIcons == null) {
+ mLauncherIcons = LauncherIcons.obtain(mContext);
+ }
+
+ mLauncherIcons.setWrapperBackgroundColor(primaryColor);
+ // User version code O, so that the icon is always wrapped in an adaptive icon container.
+ return mLauncherIcons.createBadgedIconBitmap(drawable, UserHandle.of(userId),
+ Build.VERSION_CODES.O, isInstantApp);
+ }
+
+ @Override
+ protected Drawable getBadgedActivityIcon(ActivityInfo activityInfo, int userId,
+ TaskDescription desc) {
+ BitmapInfo bitmapInfo = getBitmapInfo(
+ activityInfo.loadUnbadgedIcon(mContext.getPackageManager()),
+ userId,
+ desc.getPrimaryColor(),
+ activityInfo.applicationInfo.isInstantApp());
+ return mDrawableFactory.newIcon(bitmapInfo, activityInfo);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
new file mode 100644
index 0000000000..c856282636
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_POINTER_UP;
+import static android.view.MotionEvent.ACTION_UP;
+import static android.view.MotionEvent.INVALID_POINTER_ID;
+
+import static com.android.systemui.shared.system.ActivityManagerWrapper
+ .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+
+import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.util.SparseArray;
+import android.view.Choreographer;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.util.TraceHelper;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.AssistDataReceiver;
+import com.android.systemui.shared.system.BackgroundExecutor;
+import com.android.systemui.shared.system.NavigationBarCompat;
+import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
+import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import com.android.systemui.shared.system.RecentsAnimationListener;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Touch consumer for handling events originating from an activity other than Launcher
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
+
+ private static final long LAUNCHER_DRAW_TIMEOUT_MS = 150;
+
+ private final SparseArray mAnimationStates = new SparseArray<>();
+ private final RunningTaskInfo mRunningTask;
+ private final RecentsModel mRecentsModel;
+ private final Intent mHomeIntent;
+ private final ActivityControlHelper mActivityControlHelper;
+ private final MainThreadExecutor mMainThreadExecutor;
+ private final Choreographer mBackgroundThreadChoreographer;
+ private final OverviewCallbacks mOverviewCallbacks;
+
+ private final boolean mIsDeferredDownTarget;
+ private final PointF mDownPos = new PointF();
+ private final PointF mLastPos = new PointF();
+ private int mActivePointerId = INVALID_POINTER_ID;
+ private boolean mPassedInitialSlop;
+ // Used for non-deferred gestures to determine when to start dragging
+ private int mQuickStepDragSlop;
+ private float mStartDisplacement;
+ private WindowTransformSwipeHandler mInteractionHandler;
+ private int mDisplayRotation;
+ private Rect mStableInsets = new Rect();
+
+ private VelocityTracker mVelocityTracker;
+ private MotionEventQueue mEventQueue;
+ private boolean mIsGoingToHome;
+
+ public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
+ RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
+ MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer,
+ @HitTarget int downHitTarget, OverviewCallbacks overviewCallbacks,
+ VelocityTracker velocityTracker) {
+ super(base);
+
+ mRunningTask = runningTaskInfo;
+ mRecentsModel = recentsModel;
+ mHomeIntent = homeIntent;
+ mVelocityTracker = velocityTracker;
+ mActivityControlHelper = activityControl;
+ mMainThreadExecutor = mainThreadExecutor;
+ mBackgroundThreadChoreographer = backgroundThreadChoreographer;
+ mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget);
+ mOverviewCallbacks = overviewCallbacks;
+ }
+
+ @Override
+ public void onShowOverviewFromAltTab() {
+ startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
+ }
+
+ @Override
+ public void accept(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ return;
+ }
+ switch (ev.getActionMasked()) {
+ case ACTION_DOWN: {
+ TraceHelper.beginSection("TouchInt");
+ mActivePointerId = ev.getPointerId(0);
+ mDownPos.set(ev.getX(), ev.getY());
+ mLastPos.set(mDownPos);
+ mPassedInitialSlop = false;
+ mQuickStepDragSlop = NavigationBarCompat.getQuickStepDragSlopPx();
+
+ // Start the window animation on down to give more time for launcher to draw if the
+ // user didn't start the gesture over the back button
+ if (!mIsDeferredDownTarget) {
+ startTouchTrackingForWindowAnimation(ev.getEventTime());
+ }
+
+ Display display = getSystemService(WindowManager.class).getDefaultDisplay();
+ mDisplayRotation = display.getRotation();
+ WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
+ break;
+ }
+ case 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 ACTION_MOVE: {
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == INVALID_POINTER_ID) {
+ break;
+ }
+ mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
+ float displacement = getDisplacement(ev);
+ if (!mPassedInitialSlop) {
+ if (!mIsDeferredDownTarget) {
+ // Normal gesture, ensure we pass the drag slop before we start tracking
+ // the gesture
+ if (Math.abs(displacement) > mQuickStepDragSlop) {
+ mPassedInitialSlop = true;
+ mStartDisplacement = displacement;
+ }
+ }
+ }
+
+ if (mPassedInitialSlop && mInteractionHandler != null) {
+ // Move
+ mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
+ }
+ break;
+ }
+ case ACTION_CANCEL:
+ // TODO: Should be different than ACTION_UP
+ case ACTION_UP: {
+ TraceHelper.endSection("TouchInt");
+
+ finishTouchTracking(ev);
+ break;
+ }
+ }
+ }
+
+ private void notifyGestureStarted() {
+ if (mInteractionHandler == null) {
+ return;
+ }
+
+ mOverviewCallbacks.closeAllWindows();
+ ActivityManagerWrapper.getInstance().closeSystemWindows(
+ CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+
+ // Notify the handler that the gesture has actually started
+ mInteractionHandler.onGestureStarted();
+ }
+
+ private boolean isNavBarOnRight() {
+ return mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
+ }
+
+ private boolean isNavBarOnLeft() {
+ return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
+ }
+
+ private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
+ // Create the shared handler
+ RecentsAnimationState animationState = new RecentsAnimationState();
+ final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
+ animationState.id, mRunningTask, this, touchTimeMs, mActivityControlHelper);
+
+ // Preload the plan
+ mRecentsModel.loadTasks(mRunningTask.id, null);
+ mInteractionHandler = handler;
+ handler.setGestureEndCallback(mEventQueue::reset);
+
+ CountDownLatch drawWaitLock = new CountDownLatch(1);
+ handler.setLauncherOnDrawCallback(() -> {
+ drawWaitLock.countDown();
+ if (handler == mInteractionHandler) {
+ switchToMainChoreographer();
+ }
+ });
+ handler.initWhenReady();
+
+ TraceHelper.beginSection("RecentsController");
+ Runnable startActivity = () -> ActivityManagerWrapper.getInstance().startRecentsActivity(
+ mHomeIntent,
+ new AssistDataReceiver() {
+ @Override
+ public void onHandleAssistData(Bundle bundle) {
+ mRecentsModel.preloadAssistData(mRunningTask.id, bundle);
+ }
+ }, animationState, null, null);
+
+ if (Looper.myLooper() != Looper.getMainLooper()) {
+ startActivity.run();
+ try {
+ drawWaitLock.await(LAUNCHER_DRAW_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ // We have waited long enough for launcher to draw
+ }
+ } else {
+ // We should almost always get touch-town on background thread. This is an edge case
+ // when the background Choreographer has not yet initialized.
+ BackgroundExecutor.get().submit(startActivity);
+ }
+ }
+
+ @Override
+ public void onCommand(int command) {
+ RecentsAnimationState state = mAnimationStates.get(command);
+ if (state != null) {
+ state.execute();
+ }
+ }
+
+ /**
+ * Called when the gesture has ended. Does not correlate to the completion of the interaction as
+ * the animation can still be running.
+ */
+ private void finishTouchTracking(MotionEvent ev) {
+ if (mPassedInitialSlop && mInteractionHandler != null) {
+ mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
+
+ mVelocityTracker.computeCurrentVelocity(1000,
+ ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
+
+ float velocity = isNavBarOnRight() ? mVelocityTracker.getXVelocity(mActivePointerId)
+ : isNavBarOnLeft() ? -mVelocityTracker.getXVelocity(mActivePointerId)
+ : mVelocityTracker.getYVelocity(mActivePointerId);
+ mInteractionHandler.onGestureEnded(velocity);
+ } else {
+ // Since we start touch tracking on DOWN, we may reach this state without actually
+ // starting the gesture. In that case, just cleanup immediately.
+ reset();
+
+ // Also clean up in case the system has handled the UP and canceled the animation before
+ // we had a chance to start the recents animation. In such a case, we will not receive
+ ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
+ true /* restoreHomeStackPosition */);
+ }
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+
+ @Override
+ public void reset() {
+ // Clean up the old interaction handler
+ if (mInteractionHandler != null) {
+ final WindowTransformSwipeHandler handler = mInteractionHandler;
+ mInteractionHandler = null;
+ mIsGoingToHome = handler.mIsGoingToHome;
+ mMainThreadExecutor.execute(handler::reset);
+ }
+ }
+
+ @Override
+ public void updateTouchTracking(int interactionType) {
+ if (!mPassedInitialSlop && mIsDeferredDownTarget && mInteractionHandler == null) {
+ // If we deferred starting the window animation on touch down, then
+ // start tracking now
+ startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
+ mPassedInitialSlop = true;
+ }
+
+ if (mInteractionHandler != null) {
+ mInteractionHandler.updateInteractionType(interactionType);
+ }
+ notifyGestureStarted();
+ }
+
+ @Override
+ public Choreographer getIntrimChoreographer(MotionEventQueue queue) {
+ mEventQueue = queue;
+ return mBackgroundThreadChoreographer;
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ if (mInteractionHandler != null) {
+ mInteractionHandler.onQuickScrubEnd();
+ }
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ if (mInteractionHandler != null) {
+ mInteractionHandler.onQuickScrubProgress(progress);
+ }
+ }
+
+ @Override
+ public void onQuickStep(MotionEvent ev) {
+ if (mIsDeferredDownTarget) {
+ // Deferred gesture, start the animation and gesture tracking once we pass the actual
+ // touch slop
+ startTouchTrackingForWindowAnimation(ev.getEventTime());
+ mPassedInitialSlop = true;
+ mStartDisplacement = getDisplacement(ev);
+ }
+ notifyGestureStarted();
+ }
+
+ private float getDisplacement(MotionEvent ev) {
+ float eventX = ev.getX();
+ float eventY = ev.getY();
+ float displacement = eventY - mDownPos.y;
+ if (isNavBarOnRight()) {
+ displacement = eventX - mDownPos.x;
+ } else if (isNavBarOnLeft()) {
+ displacement = mDownPos.x - eventX;
+ }
+ return displacement;
+ }
+
+ public void switchToMainChoreographer() {
+ mEventQueue.setInterimChoreographer(null);
+ }
+
+ @Override
+ public void preProcessMotionEvent(MotionEvent ev) {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.addMovement(ev);
+ if (ev.getActionMasked() == ACTION_POINTER_UP) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
+ @Override
+ public boolean forceToLauncherConsumer() {
+ return mIsGoingToHome;
+ }
+
+ @Override
+ public boolean deferNextEventToMainThread() {
+ // TODO: Consider also check if the eventQueue is using mainThread of not.
+ return mInteractionHandler != null;
+ }
+
+ private class RecentsAnimationState implements RecentsAnimationListener {
+
+ private final int id;
+
+ private RecentsAnimationControllerCompat mController;
+ private RemoteAnimationTargetSet mTargets;
+ private Rect mHomeContentInsets;
+ private Rect mMinimizedHomeBounds;
+ private boolean mCancelled;
+
+ public RecentsAnimationState() {
+ id = mAnimationStates.size();
+ mAnimationStates.put(id, this);
+ }
+
+ @Override
+ public void onAnimationStart(
+ RecentsAnimationControllerCompat controller,
+ RemoteAnimationTargetCompat[] apps, Rect homeContentInsets,
+ Rect minimizedHomeBounds) {
+ mController = controller;
+ mTargets = new RemoteAnimationTargetSet(apps, MODE_CLOSING);
+ mHomeContentInsets = homeContentInsets;
+ mMinimizedHomeBounds = minimizedHomeBounds;
+ mEventQueue.onCommand(id);
+ }
+
+ @Override
+ public void onAnimationCanceled() {
+ mCancelled = true;
+ mEventQueue.onCommand(id);
+ }
+
+ public void execute() {
+ if (mInteractionHandler == null || mInteractionHandler.id != id) {
+ if (!mCancelled && mController != null) {
+ TraceHelper.endSection("RecentsController", "Finishing no handler");
+ mController.finish(false /* toHome */);
+ }
+ } else if (mCancelled) {
+ TraceHelper.endSection("RecentsController",
+ "Cancelled: " + mInteractionHandler);
+ mInteractionHandler.onRecentsAnimationCanceled();
+ } else {
+ TraceHelper.partitionSection("RecentsController", "Received");
+ mInteractionHandler.onRecentsAnimationStart(mController, mTargets,
+ mHomeContentInsets, mMinimizedHomeBounds);
+ }
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/OverviewCallbacks.java b/quickstep/src/com/android/quickstep/OverviewCallbacks.java
new file mode 100644
index 0000000000..ac4a40b983
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/OverviewCallbacks.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.content.Context;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Preconditions;
+
+/**
+ * Callbacks related to overview/quicksteps.
+ */
+public class OverviewCallbacks {
+
+ private static OverviewCallbacks sInstance;
+
+ public static OverviewCallbacks get(Context context) {
+ Preconditions.assertUIThread();
+ if (sInstance == null) {
+ sInstance = Utilities.getOverrideObject(OverviewCallbacks.class,
+ context.getApplicationContext(), R.string.overview_callbacks_class);
+ }
+ return sInstance;
+ }
+
+ public void onInitOverviewTransition() { }
+
+ public void onResetOverview() { }
+
+ public void closeAllWindows() { }
+}
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
new file mode 100644
index 0000000000..41a45501d0
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_CHANGED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
+import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
+import static com.android.systemui.shared.system.ActivityManagerWrapper
+ .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.systemui.shared.system.PackageManagerWrapper
+ .ACTION_PREFERRED_ACTIVITY_CHANGED;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.PatternMatcher;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
+import com.android.quickstep.ActivityControlHelper.AnimationFactory;
+import com.android.quickstep.ActivityControlHelper.FallbackActivityControllerHelper;
+import com.android.quickstep.ActivityControlHelper.LauncherActivityControllerHelper;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.TransformedRect;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.LatencyTrackerCompat;
+import com.android.systemui.shared.system.PackageManagerWrapper;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+
+import java.util.ArrayList;
+
+/**
+ * Helper class to handle various atomic commands for switching between Overview.
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class OverviewCommandHelper {
+
+ private static final long RECENTS_LAUNCH_DURATION = 250;
+
+ private static final String TAG = "OverviewCommandHelper";
+
+ private final Context mContext;
+ private final ActivityManagerWrapper mAM;
+ private final RecentsModel mRecentsModel;
+ private final MainThreadExecutor mMainThreadExecutor;
+ private final ComponentName mMyHomeComponent;
+
+ private final BroadcastReceiver mUserPreferenceChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ initOverviewTargets();
+ }
+ };
+ private final BroadcastReceiver mOtherHomeAppUpdateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ initOverviewTargets();
+ }
+ };
+ private String mUpdateRegisteredPackage;
+
+ public Intent overviewIntent;
+ public ComponentName overviewComponent;
+ private ActivityControlHelper mActivityControlHelper;
+
+ private long mLastToggleTime;
+
+ public OverviewCommandHelper(Context context) {
+ mContext = context;
+ mAM = ActivityManagerWrapper.getInstance();
+ mMainThreadExecutor = new MainThreadExecutor();
+ mRecentsModel = RecentsModel.getInstance(mContext);
+
+ Intent myHomeIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setPackage(mContext.getPackageName());
+ ResolveInfo info = context.getPackageManager().resolveActivity(myHomeIntent, 0);
+ mMyHomeComponent = new ComponentName(context.getPackageName(), info.activityInfo.name);
+
+ mContext.registerReceiver(mUserPreferenceChangeReceiver,
+ new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED));
+ initOverviewTargets();
+ }
+
+ private void initOverviewTargets() {
+ ComponentName defaultHome = PackageManagerWrapper.getInstance()
+ .getHomeActivities(new ArrayList<>());
+
+ final String overviewIntentCategory;
+ if (defaultHome == null || mMyHomeComponent.equals(defaultHome)) {
+ // User default home is same as out home app. Use Overview integrated in Launcher.
+ overviewComponent = mMyHomeComponent;
+ mActivityControlHelper = new LauncherActivityControllerHelper();
+ overviewIntentCategory = Intent.CATEGORY_HOME;
+
+ if (mUpdateRegisteredPackage != null) {
+ // Remove any update listener as we don't care about other packages.
+ mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
+ mUpdateRegisteredPackage = null;
+ }
+ } else {
+ // The default home app is a different launcher. Use the fallback Overview instead.
+ overviewComponent = new ComponentName(mContext, RecentsActivity.class);
+ mActivityControlHelper = new FallbackActivityControllerHelper(defaultHome);
+ overviewIntentCategory = Intent.CATEGORY_DEFAULT;
+
+ // User's default home app can change as a result of package updates of this app (such
+ // as uninstalling the app or removing the "Launcher" feature in an update).
+ // Listen for package updates of this app (and remove any previously attached
+ // package listener).
+ if (!defaultHome.getPackageName().equals(mUpdateRegisteredPackage)) {
+ if (mUpdateRegisteredPackage != null) {
+ mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
+ }
+
+ mUpdateRegisteredPackage = defaultHome.getPackageName();
+ IntentFilter updateReceiver = new IntentFilter(ACTION_PACKAGE_ADDED);
+ updateReceiver.addAction(ACTION_PACKAGE_CHANGED);
+ updateReceiver.addAction(ACTION_PACKAGE_REMOVED);
+ updateReceiver.addDataScheme("package");
+ updateReceiver.addDataSchemeSpecificPart(mUpdateRegisteredPackage,
+ PatternMatcher.PATTERN_LITERAL);
+ mContext.registerReceiver(mOtherHomeAppUpdateReceiver, updateReceiver);
+ }
+ }
+
+ overviewIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(overviewIntentCategory)
+ .setComponent(overviewComponent)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ }
+
+ public void onDestroy() {
+ mContext.unregisterReceiver(mUserPreferenceChangeReceiver);
+
+ if (mUpdateRegisteredPackage != null) {
+ mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
+ mUpdateRegisteredPackage = null;
+ }
+ }
+
+ public void onOverviewToggle() {
+ // If currently screen pinning, do not enter overview
+ if (mAM.isScreenPinningActive()) {
+ return;
+ }
+
+ mAM.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ mMainThreadExecutor.execute(new RecentsActivityCommand<>());
+ }
+
+ public void onOverviewShown() {
+ mMainThreadExecutor.execute(new ShowRecentsCommand());
+ }
+
+ public void onTip(int actionType, int viewType) {
+ mMainThreadExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ UserEventDispatcher.newInstance(mContext,
+ new InvariantDeviceProfile(mContext).getDeviceProfile(mContext))
+ .logActionTip(actionType, viewType);
+ }
+ });
+ }
+
+ public ActivityControlHelper getActivityControlHelper() {
+ return mActivityControlHelper;
+ }
+
+ private class ShowRecentsCommand extends RecentsActivityCommand {
+
+ @Override
+ protected boolean handleCommand(long elapsedTime) {
+ return mHelper.getVisibleRecentsView() != null;
+ }
+ }
+
+ private class RecentsActivityCommand implements Runnable {
+
+ protected final ActivityControlHelper mHelper;
+ private final long mCreateTime;
+ private final int mRunningTaskId;
+
+ private ActivityInitListener mListener;
+ private T mActivity;
+ private RecentsView mRecentsView;
+ private final long mToggleClickedTime = SystemClock.uptimeMillis();
+ private boolean mUserEventLogged;
+
+ public RecentsActivityCommand() {
+ mHelper = getActivityControlHelper();
+ mCreateTime = SystemClock.elapsedRealtime();
+ mRunningTaskId = mAM.getRunningTask().id;
+
+ // Preload the plan
+ mRecentsModel.loadTasks(mRunningTaskId, null);
+ }
+
+ @Override
+ public void run() {
+ long elapsedTime = mCreateTime - mLastToggleTime;
+ mLastToggleTime = mCreateTime;
+
+ if (!handleCommand(elapsedTime)) {
+ // Start overview
+ if (!mHelper.switchToRecentsIfVisible(true)) {
+ mListener = mHelper.createActivityInitListener(this::onActivityReady);
+ mListener.registerAndStartActivity(overviewIntent, this::createWindowAnimation,
+ mContext, mMainThreadExecutor.getHandler(), RECENTS_LAUNCH_DURATION);
+ }
+ }
+ }
+
+ protected boolean handleCommand(long elapsedTime) {
+ // TODO: We need to fix this case with PIP, when an activity first enters PIP, it shows
+ // the menu activity which takes window focus, preventing the right condition from
+ // being run below
+ RecentsView recents = mHelper.getVisibleRecentsView();
+ if (recents != null) {
+ // Launch the next task
+ recents.showNextTask();
+ return true;
+ } else if (elapsedTime < ViewConfiguration.getDoubleTapTimeout()) {
+ // The user tried to launch back into overview too quickly, either after
+ // launching an app, or before overview has actually shown, just ignore for now
+ return true;
+ }
+ return false;
+ }
+
+ private boolean onActivityReady(T activity, Boolean wasVisible) {
+ activity.getOverviewPanel().setCurrentTask(mRunningTaskId);
+ AbstractFloatingView.closeAllOpenViews(activity, wasVisible);
+ AnimationFactory factory = mHelper.prepareRecentsUI(activity, wasVisible,
+ (controller) -> {
+ controller.dispatchOnStart();
+ ValueAnimator anim = controller.getAnimationPlayer()
+ .setDuration(RECENTS_LAUNCH_DURATION);
+ anim.setInterpolator(FAST_OUT_SLOW_IN);
+ anim.start();
+ });
+ factory.onRemoteAnimationReceived(null);
+ if (wasVisible) {
+ factory.createActivityController(RECENTS_LAUNCH_DURATION, INTERACTION_NORMAL);
+ }
+ mActivity = activity;
+ mRecentsView = mActivity.getOverviewPanel();
+ mRecentsView.setRunningTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
+ if (!mUserEventLogged) {
+ activity.getUserEventDispatcher().logActionCommand(Action.Command.RECENTS_BUTTON,
+ mHelper.getContainerType(), ContainerType.TASKSWITCHER);
+ mUserEventLogged = true;
+ }
+ return false;
+ }
+
+ private AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targetCompats) {
+ if (LatencyTrackerCompat.isEnabled(mContext)) {
+ LatencyTrackerCompat.logToggleRecents(
+ (int) (SystemClock.uptimeMillis() - mToggleClickedTime));
+ }
+
+ if (mListener != null) {
+ mListener.unregister();
+ }
+ AnimatorSet anim = new AnimatorSet();
+ anim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ if (mRecentsView != null) {
+ mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */,
+ true /* animate */);
+ }
+ }
+ });
+ if (mActivity == null) {
+ Log.e(TAG, "Animation created, before activity");
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(100));
+ return anim;
+ }
+
+ RemoteAnimationTargetSet targetSet =
+ new RemoteAnimationTargetSet(targetCompats, MODE_CLOSING);
+
+ // Use the top closing app to determine the insets for the animation
+ RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
+ if (runningTaskTarget == null) {
+ Log.e(TAG, "No closing app");
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(100));
+ return anim;
+ }
+
+ final ClipAnimationHelper clipHelper = new ClipAnimationHelper();
+
+ // At this point, the activity is already started and laid-out. Get the home-bounds
+ // relative to the screen using the rootView of the activity.
+ int loc[] = new int[2];
+ View rootView = mActivity.getRootView();
+ rootView.getLocationOnScreen(loc);
+ Rect homeBounds = new Rect(loc[0], loc[1],
+ loc[0] + rootView.getWidth(), loc[1] + rootView.getHeight());
+ clipHelper.updateSource(homeBounds, runningTaskTarget);
+
+ TransformedRect targetRect = new TransformedRect();
+ mHelper.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity,
+ INTERACTION_NORMAL, targetRect);
+ clipHelper.updateTargetRect(targetRect);
+ clipHelper.prepareAnimation(false /* isOpening */);
+
+ ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
+ valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
+ valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
+ valueAnimator.addUpdateListener((v) ->
+ clipHelper.applyTransform(targetSet, (float) v.getAnimatedValue()));
+
+ if (targetSet.isAnimatingHome()) {
+ // If we are animating home, fade in the opening targets
+ RemoteAnimationTargetSet openingSet =
+ new RemoteAnimationTargetSet(targetCompats, MODE_OPENING);
+
+ TransactionCompat transaction = new TransactionCompat();
+ valueAnimator.addUpdateListener((v) -> {
+ for (RemoteAnimationTargetCompat app : openingSet.apps) {
+ transaction.setAlpha(app.leash, (float) v.getAnimatedValue());
+ }
+ transaction.apply();
+ });
+ }
+ anim.play(valueAnimator);
+ return anim;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
new file mode 100644
index 0000000000..922a7ff295
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
+import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
+import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
+import static com.android.systemui.shared.system.SettingsCompat.SWIPE_UP_SETTING_NAME;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.support.annotation.WorkerThread;
+import android.util.Log;
+
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.DiscoveryBounce;
+import com.android.launcher3.util.UiThreadHelper;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Sets overview interaction flags, such as:
+ *
+ * - FLAG_DISABLE_QUICK_SCRUB
+ * - FLAG_DISABLE_SWIPE_UP
+ * - FLAG_SHOW_OVERVIEW_BUTTON
+ *
+ * @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags.
+ */
+public class OverviewInteractionState {
+
+ private static final String TAG = "OverviewFlags";
+
+ private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
+ private static final String SWIPE_UP_SETTING_AVAILABLE_RES_NAME =
+ "config_swipe_up_gesture_setting_available";
+ private static final String SWIPE_UP_ENABLED_DEFAULT_RES_NAME =
+ "config_swipe_up_gesture_default";
+
+ // We do not need any synchronization for this variable as its only written on UI thread.
+ private static OverviewInteractionState INSTANCE;
+
+ public static OverviewInteractionState getInstance(final Context context) {
+ if (INSTANCE == null) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ INSTANCE = new OverviewInteractionState(context.getApplicationContext());
+ } else {
+ try {
+ return new MainThreadExecutor().submit(
+ () -> OverviewInteractionState.getInstance(context)).get();
+ } catch (InterruptedException|ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return INSTANCE;
+ }
+
+ private static final int MSG_SET_PROXY = 200;
+ private static final int MSG_SET_BACK_BUTTON_ALPHA = 201;
+ private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
+
+ private final SwipeUpGestureEnabledSettingObserver mSwipeUpSettingObserver;
+
+ private final Context mContext;
+ private final Handler mUiHandler;
+ private final Handler mBgHandler;
+
+ // These are updated on the background thread
+ private ISystemUiProxy mISystemUiProxy;
+ private boolean mSwipeUpEnabled = true;
+ private float mBackButtonAlpha = 1;
+
+ private Runnable mOnSwipeUpSettingChangedListener;
+
+ private OverviewInteractionState(Context context) {
+ mContext = context;
+
+ // Data posted to the uihandler will be sent to the bghandler. Data is sent to uihandler
+ // because of its high send frequency and data may be very different than the previous value
+ // For example, send back alpha on uihandler to avoid flickering when setting its visibility
+ mUiHandler = new Handler(this::handleUiMessage);
+ mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
+
+ if (getSystemBooleanRes(SWIPE_UP_SETTING_AVAILABLE_RES_NAME)) {
+ mSwipeUpSettingObserver = new SwipeUpGestureEnabledSettingObserver(mUiHandler,
+ context.getContentResolver());
+ mSwipeUpSettingObserver.register();
+ } else {
+ mSwipeUpSettingObserver = null;
+ mSwipeUpEnabled = getSystemBooleanRes(SWIPE_UP_ENABLED_DEFAULT_RES_NAME);
+ }
+ }
+
+ public boolean isSwipeUpGestureEnabled() {
+ return mSwipeUpEnabled;
+ }
+
+ public float getBackButtonAlpha() {
+ return mBackButtonAlpha;
+ }
+
+ public void setBackButtonAlpha(float alpha, boolean animate) {
+ if (!mSwipeUpEnabled) {
+ alpha = 1;
+ }
+ mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_ALPHA);
+ mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_ALPHA, animate ? 1 : 0, 0, alpha)
+ .sendToTarget();
+ }
+
+ public void setSystemUiProxy(ISystemUiProxy proxy) {
+ mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
+ }
+
+ private boolean handleUiMessage(Message msg) {
+ if (msg.what == MSG_SET_BACK_BUTTON_ALPHA) {
+ mBackButtonAlpha = (float) msg.obj;
+ }
+ mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2, msg.obj).sendToTarget();
+ return true;
+ }
+
+ private boolean handleBgMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SET_PROXY:
+ mISystemUiProxy = (ISystemUiProxy) msg.obj;
+ break;
+ case MSG_SET_BACK_BUTTON_ALPHA:
+ applyBackButtonAlpha((float) msg.obj, msg.arg1 == 1);
+ return true;
+ case MSG_SET_SWIPE_UP_ENABLED:
+ mSwipeUpEnabled = msg.arg1 != 0;
+ resetHomeBounceSeenOnQuickstepEnabledFirstTime();
+
+ if (mOnSwipeUpSettingChangedListener != null) {
+ mOnSwipeUpSettingChangedListener.run();
+ }
+ break;
+ }
+ applyFlags();
+ return true;
+ }
+
+ public void setOnSwipeUpSettingChangedListener(Runnable listener) {
+ mOnSwipeUpSettingChangedListener = listener;
+ }
+
+ @WorkerThread
+ private void applyFlags() {
+ if (mISystemUiProxy == null) {
+ return;
+ }
+
+ int flags = 0;
+ if (!mSwipeUpEnabled) {
+ flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
+ }
+ try {
+ mISystemUiProxy.setInteractionState(flags);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to update overview interaction flags", e);
+ }
+ }
+
+ @WorkerThread
+ private void applyBackButtonAlpha(float alpha, boolean animate) {
+ if (mISystemUiProxy == null) {
+ return;
+ }
+ try {
+ mISystemUiProxy.setBackButtonAlpha(alpha, animate);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to update overview back button alpha", e);
+ }
+ }
+
+ private class SwipeUpGestureEnabledSettingObserver extends ContentObserver {
+ private Handler mHandler;
+ private ContentResolver mResolver;
+ private final int defaultValue;
+
+ SwipeUpGestureEnabledSettingObserver(Handler handler, ContentResolver resolver) {
+ super(handler);
+ mHandler = handler;
+ mResolver = resolver;
+ defaultValue = getSystemBooleanRes(SWIPE_UP_ENABLED_DEFAULT_RES_NAME) ? 1 : 0;
+ }
+
+ public void register() {
+ mResolver.registerContentObserver(Settings.Secure.getUriFor(SWIPE_UP_SETTING_NAME),
+ false, this);
+ mSwipeUpEnabled = getValue();
+ resetHomeBounceSeenOnQuickstepEnabledFirstTime();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ mHandler.removeMessages(MSG_SET_SWIPE_UP_ENABLED);
+ mHandler.obtainMessage(MSG_SET_SWIPE_UP_ENABLED, getValue() ? 1 : 0, 0).sendToTarget();
+ }
+
+ private boolean getValue() {
+ return Settings.Secure.getInt(mResolver, SWIPE_UP_SETTING_NAME, defaultValue) == 1;
+ }
+ }
+
+ private boolean getSystemBooleanRes(String resName) {
+ Resources res = Resources.getSystem();
+ int resId = res.getIdentifier(resName, "bool", "android");
+
+ if (resId != 0) {
+ return res.getBoolean(resId);
+ } else {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ return false;
+ }
+ }
+
+ private void resetHomeBounceSeenOnQuickstepEnabledFirstTime() {
+ if (mSwipeUpEnabled && !Utilities.getPrefs(mContext).getBoolean(
+ HAS_ENABLED_QUICKSTEP_ONCE, true)) {
+ Utilities.getPrefs(mContext).edit()
+ .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)
+ .putBoolean(DiscoveryBounce.HOME_BOUNCE_SEEN, false)
+ .apply();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
new file mode 100644
index 0000000000..7a79c6f4df
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Alarm;
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.OnAlarmListener;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+
+/**
+ * Responds to quick scrub callbacks to page through and launch recent tasks.
+ *
+ * The behavior is to evenly divide the progress into sections, each of which scrolls one page.
+ * The first and last section set an alarm to auto-advance backwards or forwards, respectively.
+ */
+public class QuickScrubController implements OnAlarmListener {
+
+ public static final int QUICK_SCRUB_FROM_APP_START_DURATION = 240;
+ public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 200;
+ // We want the translation y to finish faster than the rest of the animation.
+ public static final float QUICK_SCRUB_TRANSLATION_Y_FACTOR = 5f / 6;
+ public static final Interpolator QUICK_SCRUB_START_INTERPOLATOR = FAST_OUT_SLOW_IN;
+
+ /**
+ * Snap to a new page when crossing these thresholds. The first and last auto-advance.
+ */
+ private static final float[] QUICK_SCRUB_THRESHOLDS = new float[] {
+ 0.05f, 0.20f, 0.35f, 0.50f, 0.65f, 0.80f, 0.95f
+ };
+
+ private static final String TAG = "QuickScrubController";
+ private static final boolean ENABLE_AUTO_ADVANCE = true;
+ private static final long AUTO_ADVANCE_DELAY = 500;
+ private static final int QUICKSCRUB_SNAP_DURATION_PER_PAGE = 325;
+ private static final int QUICKSCRUB_END_SNAP_DURATION_PER_PAGE = 60;
+
+ private final Alarm mAutoAdvanceAlarm;
+ private final RecentsView mRecentsView;
+ private final BaseActivity mActivity;
+
+ private boolean mInQuickScrub;
+ private boolean mWaitingForTaskLaunch;
+ private int mQuickScrubSection;
+ private boolean mStartedFromHome;
+ private boolean mFinishedTransitionToQuickScrub;
+ private Runnable mOnFinishedTransitionToQuickScrubRunnable;
+ private ActivityControlHelper mActivityControlHelper;
+
+ public QuickScrubController(BaseActivity activity, RecentsView recentsView) {
+ mActivity = activity;
+ mRecentsView = recentsView;
+ if (ENABLE_AUTO_ADVANCE) {
+ mAutoAdvanceAlarm = new Alarm();
+ mAutoAdvanceAlarm.setOnAlarmListener(this);
+ }
+ }
+
+ public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper) {
+ prepareQuickScrub(TAG);
+ mInQuickScrub = true;
+ mStartedFromHome = startingFromHome;
+ mQuickScrubSection = 0;
+ mFinishedTransitionToQuickScrub = false;
+ mActivityControlHelper = controlHelper;
+
+ snapToNextTaskIfAvailable();
+ mActivity.getUserEventDispatcher().resetActionDurationMillis();
+ }
+
+ public void onQuickScrubEnd() {
+ mInQuickScrub = false;
+ if (ENABLE_AUTO_ADVANCE) {
+ mAutoAdvanceAlarm.cancelAlarm();
+ }
+ int page = mRecentsView.getNextPage();
+ Runnable launchTaskRunnable = () -> {
+ TaskView taskView = mRecentsView.getPageAt(page);
+ if (taskView != null) {
+ mWaitingForTaskLaunch = true;
+ taskView.launchTask(true, (result) -> {
+ if (!result) {
+ taskView.notifyTaskLaunchFailed(TAG);
+ breakOutOfQuickScrub();
+ } else {
+ mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
+ LauncherLogProto.Action.Direction.NONE, page,
+ TaskUtils.getComponentKeyForTask(taskView.getTask().key));
+ }
+ mWaitingForTaskLaunch = false;
+ }, taskView.getHandler());
+ } else {
+ breakOutOfQuickScrub();
+ }
+ mActivityControlHelper = null;
+ };
+ int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
+ * QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
+ if (mRecentsView.getChildCount() > 0 && mRecentsView.snapToPage(page, snapDuration)) {
+ // Settle on the page then launch it
+ mRecentsView.setNextPageSwitchRunnable(launchTaskRunnable);
+ } else {
+ // No page move needed, just launch it
+ if (mFinishedTransitionToQuickScrub) {
+ launchTaskRunnable.run();
+ } else {
+ mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable;
+ }
+ }
+ }
+
+ public void cancelActiveQuickscrub() {
+ if (!mInQuickScrub) {
+ return;
+ }
+ Log.d(TAG, "Quickscrub was active, cancelling");
+ mInQuickScrub = false;
+ mActivityControlHelper = null;
+ mOnFinishedTransitionToQuickScrubRunnable = null;
+ mRecentsView.setNextPageSwitchRunnable(null);
+ }
+
+ /**
+ * Initializes the UI for quick scrub, returns true if success.
+ */
+ public boolean prepareQuickScrub(String tag) {
+ if (mWaitingForTaskLaunch || mInQuickScrub) {
+ Log.d(tag, "Waiting for last scrub to finish, will skip this interaction");
+ return false;
+ }
+ mOnFinishedTransitionToQuickScrubRunnable = null;
+ mRecentsView.setNextPageSwitchRunnable(null);
+ return true;
+ }
+
+ public boolean isWaitingForTaskLaunch() {
+ return mWaitingForTaskLaunch;
+ }
+
+ /**
+ * Attempts to go to normal overview or back to home, so UI doesn't prevent user interaction.
+ */
+ private void breakOutOfQuickScrub() {
+ if (mRecentsView.getChildCount() == 0 || mActivityControlHelper == null
+ || !mActivityControlHelper.switchToRecentsIfVisible(false)) {
+ mActivity.onBackPressed();
+ }
+ }
+
+ public void onQuickScrubProgress(float progress) {
+ int quickScrubSection = 0;
+ for (float threshold : QUICK_SCRUB_THRESHOLDS) {
+ if (progress < threshold) {
+ break;
+ }
+ quickScrubSection++;
+ }
+ if (quickScrubSection != mQuickScrubSection) {
+ boolean cameFromAutoAdvance = mQuickScrubSection == QUICK_SCRUB_THRESHOLDS.length
+ || mQuickScrubSection == 0;
+ int pageToGoTo = mRecentsView.getNextPage() + quickScrubSection - mQuickScrubSection;
+ if (mFinishedTransitionToQuickScrub && !cameFromAutoAdvance) {
+ goToPageWithHaptic(pageToGoTo);
+ }
+ if (ENABLE_AUTO_ADVANCE) {
+ if (quickScrubSection == QUICK_SCRUB_THRESHOLDS.length || quickScrubSection == 0) {
+ mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
+ } else {
+ mAutoAdvanceAlarm.cancelAlarm();
+ }
+ }
+ mQuickScrubSection = quickScrubSection;
+ }
+ }
+
+ public void onFinishedTransitionToQuickScrub() {
+ mFinishedTransitionToQuickScrub = true;
+ Runnable action = mOnFinishedTransitionToQuickScrubRunnable;
+ // Clear the runnable before executing it, to prevent potential recursion.
+ mOnFinishedTransitionToQuickScrubRunnable = null;
+ if (action != null) {
+ action.run();
+ }
+ }
+
+ public void snapToNextTaskIfAvailable() {
+ if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
+ int duration = mStartedFromHome ? QUICK_SCRUB_FROM_HOME_START_DURATION
+ : QUICK_SCRUB_FROM_APP_START_DURATION;
+ int pageToGoTo = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
+ goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */,
+ QUICK_SCRUB_START_INTERPOLATOR);
+ }
+ }
+
+ private void goToPageWithHaptic(int pageToGoTo) {
+ goToPageWithHaptic(pageToGoTo, -1 /* overrideDuration */, false /* forceHaptic */, null);
+ }
+
+ private void goToPageWithHaptic(int pageToGoTo, int overrideDuration, boolean forceHaptic,
+ Interpolator interpolator) {
+ pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
+ boolean snappingToPage = pageToGoTo != mRecentsView.getNextPage();
+ if (snappingToPage) {
+ int duration = overrideDuration > -1 ? overrideDuration
+ : Math.abs(pageToGoTo - mRecentsView.getNextPage())
+ * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
+ mRecentsView.snapToPage(pageToGoTo, duration, interpolator);
+ }
+ if (snappingToPage || forceHaptic) {
+ mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ }
+ }
+
+ @Override
+ public void onAlarm(Alarm alarm) {
+ int currPage = mRecentsView.getNextPage();
+ boolean recentsVisible = mActivityControlHelper != null
+ && mActivityControlHelper.getVisibleRecentsView() != null;
+ if (!recentsVisible) {
+ Log.w(TAG, "Failed to auto advance; recents not visible");
+ return;
+ }
+ if (mQuickScrubSection == QUICK_SCRUB_THRESHOLDS.length
+ && currPage < mRecentsView.getPageCount() - 1) {
+ goToPageWithHaptic(currPage + 1);
+ } else if (mQuickScrubSection == 0 && currPage > 0) {
+ goToPageWithHaptic(currPage - 1);
+ }
+ if (ENABLE_AUTO_ADVANCE) {
+ mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
new file mode 100644
index 0000000000..2c3f77f213
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.content.Context;
+
+import com.android.launcher3.MainProcessInitializer;
+import com.android.systemui.shared.system.ThreadedRendererCompat;
+
+@SuppressWarnings("unused")
+public class QuickstepProcessInitializer extends MainProcessInitializer {
+
+ public QuickstepProcessInitializer(Context context) { }
+
+ @Override
+ protected void init(Context context) {
+ super.init(context);
+
+ // Elevate GPU priority for Quickstep and Remote animations.
+ ThreadedRendererCompat.setContextPriority(ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_HIGH_IMG);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
new file mode 100644
index 0000000000..3adb290bb8
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -0,0 +1,284 @@
+/*
+ * 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.quickstep;
+
+import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
+import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+
+import static com.android.launcher3.LauncherAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
+import static com.android.launcher3.LauncherAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION;
+import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
+import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.badge.BadgeInfo;
+import com.android.launcher3.uioverrides.UiFactory;
+import com.android.launcher3.util.SystemUiController;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.fallback.FallbackRecentsView;
+import com.android.quickstep.fallback.RecentsRootView;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.views.RecentsViewContainer;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
+import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * A simple activity to show the recently launched tasks
+ */
+public class RecentsActivity extends BaseDraggingActivity {
+
+ private Handler mUiHandler = new Handler(Looper.getMainLooper());
+ private RecentsRootView mRecentsRootView;
+ private FallbackRecentsView mFallbackRecentsView;
+ private RecentsViewContainer mOverviewPanelContainer;
+
+ private Configuration mOldConfig;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mOldConfig = new Configuration(getResources().getConfiguration());
+ initDeviceProfile();
+
+ setContentView(R.layout.fallback_recents_activity);
+ mRecentsRootView = findViewById(R.id.drag_layer);
+ mFallbackRecentsView = findViewById(R.id.overview_panel);
+ mOverviewPanelContainer = findViewById(R.id.overview_panel_container);
+
+ mRecentsRootView.setup();
+
+ getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
+ Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
+ RecentsActivityTracker.onRecentsActivityCreate(this);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ int diff = newConfig.diff(mOldConfig);
+ if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
+ onHandleConfigChanged();
+ }
+ mOldConfig.setTo(newConfig);
+ super.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
+ onHandleConfigChanged();
+ super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
+ }
+
+ public void onRootViewSizeChanged() {
+ if (isInMultiWindowModeCompat()) {
+ onHandleConfigChanged();
+ }
+ }
+
+ private void onHandleConfigChanged() {
+ mUserEventDispatcher = null;
+ initDeviceProfile();
+
+ AbstractFloatingView.closeOpenViews(this, true,
+ AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
+ dispatchDeviceProfileChanged();
+
+ mRecentsRootView.setup();
+ reapplyUi();
+ }
+
+ @Override
+ protected void reapplyUi() {
+ mRecentsRootView.dispatchInsets();
+ }
+
+ private void initDeviceProfile() {
+ // In case we are reusing IDP, create a copy so that we dont conflict with Launcher
+ // activity.
+ LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
+ if (isInMultiWindowModeCompat()) {
+ InvariantDeviceProfile idp = appState == null
+ ? new InvariantDeviceProfile(this) : appState.getInvariantDeviceProfile();
+ DeviceProfile dp = idp.getDeviceProfile(this);
+ mDeviceProfile = mRecentsRootView == null ? dp.copy(this)
+ : dp.getMultiWindowProfile(this, mRecentsRootView.getLastKnownSize());
+ } else {
+ // If we are reusing the Invariant device profile, make a copy.
+ mDeviceProfile = appState == null
+ ? new InvariantDeviceProfile(this).getDeviceProfile(this)
+ : appState.getInvariantDeviceProfile().getDeviceProfile(this).copy(this);
+ }
+ onDeviceProfileInitiated();
+ }
+
+ @Override
+ public BaseDragLayer getDragLayer() {
+ return mRecentsRootView;
+ }
+
+ @Override
+ public View getRootView() {
+ return mRecentsRootView;
+ }
+
+ @Override
+ public T getOverviewPanel() {
+ return (T) mFallbackRecentsView;
+ }
+
+ public RecentsViewContainer getOverviewPanelContainer() {
+ return mOverviewPanelContainer;
+ }
+
+ @Override
+ public BadgeInfo getBadgeInfoForItem(ItemInfo info) {
+ return null;
+ }
+
+ @Override
+ public ActivityOptions getActivityLaunchOptions(final View v) {
+ if (!(v instanceof TaskView)) {
+ return null;
+ }
+
+ final TaskView taskView = (TaskView) v;
+ RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mUiHandler,
+ true /* startAtFrontOfQueue */) {
+
+ @Override
+ public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
+ AnimationResult result) {
+ result.setAnimation(composeRecentsLaunchAnimator(taskView, targetCompats));
+ }
+ };
+ return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
+ runner, RECENTS_LAUNCH_DURATION,
+ RECENTS_LAUNCH_DURATION - STATUS_BAR_TRANSITION_DURATION));
+ }
+
+ /**
+ * Composes the animations for a launch from the recents list if possible.
+ */
+ private AnimatorSet composeRecentsLaunchAnimator(TaskView taskView,
+ RemoteAnimationTargetCompat[] targets) {
+ AnimatorSet target = new AnimatorSet();
+ boolean activityClosing = taskIsATargetWithMode(targets, getTaskId(), MODE_CLOSING);
+ ClipAnimationHelper helper = new ClipAnimationHelper();
+ target.play(getRecentsWindowAnimator(taskView, !activityClosing, targets, helper)
+ .setDuration(RECENTS_LAUNCH_DURATION));
+
+ // Found a visible recents task that matches the opening app, lets launch the app from there
+ if (activityClosing) {
+ Animator adjacentAnimation = mFallbackRecentsView
+ .createAdjacentPageAnimForTaskLaunch(taskView, helper);
+ adjacentAnimation.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
+ adjacentAnimation.setDuration(RECENTS_LAUNCH_DURATION);
+ adjacentAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mFallbackRecentsView.resetTaskVisuals();
+ }
+ });
+ target.play(adjacentAnimation);
+ }
+ return target;
+ }
+
+ @Override
+ public void invalidateParent(ItemInfo info) { }
+
+ @Override
+ protected void onStart() {
+ // Set the alpha to 1 before calling super, as it may get set back to 0 due to
+ // onActivityStart callback.
+ mFallbackRecentsView.setContentAlpha(1);
+ super.onStart();
+ UiFactory.onStart(this);
+ mFallbackRecentsView.resetTaskVisuals();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // Workaround for b/78520668, explicitly trim memory once UI is hidden
+ onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+ super.onTrimMemory(level);
+ UiFactory.onTrimMemory(this, level);
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ RecentsActivityTracker.onRecentsActivityNewIntent(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ RecentsActivityTracker.onRecentsActivityDestroy(this);
+ }
+
+ @Override
+ public void onBackPressed() {
+ // TODO: Launch the task we came from
+ startHome();
+ }
+
+ public void startHome() {
+ startActivity(new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
+
+ @Override
+ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ super.dump(prefix, fd, writer, args);
+ writer.println(prefix + "Misc:");
+ dumpMisc(writer);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
new file mode 100644
index 0000000000..fb6090e2a5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+
+import com.android.launcher3.MainThreadExecutor;
+import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
+import com.android.quickstep.util.RemoteAnimationProvider;
+
+import java.lang.ref.WeakReference;
+import java.util.function.BiPredicate;
+
+/**
+ * Utility class to track create/destroy for RecentsActivity
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class RecentsActivityTracker implements ActivityInitListener {
+
+ private static WeakReference sCurrentActivity = new WeakReference<>(null);
+ private static final Scheduler sScheduler = new Scheduler();
+
+ private final BiPredicate mOnInitListener;
+
+ public RecentsActivityTracker(BiPredicate onInitListener) {
+ mOnInitListener = onInitListener;
+ }
+
+ @Override
+ public void register() {
+ sScheduler.schedule(this);
+ }
+
+ @Override
+ public void unregister() {
+ sScheduler.clearReference(this);
+ }
+
+ private boolean init(RecentsActivity activity, boolean visible) {
+ return mOnInitListener.test(activity, visible);
+ }
+
+ public static RecentsActivity getCurrentActivity() {
+ return sCurrentActivity.get();
+ }
+
+ @Override
+ public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
+ Context context, Handler handler, long duration) {
+ register();
+
+ Bundle options = animProvider.toActivityOptions(handler, duration).toBundle();
+ context.startActivity(intent, options);
+ }
+
+ public static void onRecentsActivityCreate(RecentsActivity activity) {
+ sCurrentActivity = new WeakReference<>(activity);
+ sScheduler.initIfPending(activity, false);
+ }
+
+
+ public static void onRecentsActivityNewIntent(RecentsActivity activity) {
+ sScheduler.initIfPending(activity, activity.isStarted());
+ }
+
+ public static void onRecentsActivityDestroy(RecentsActivity activity) {
+ if (sCurrentActivity.get() == activity) {
+ sCurrentActivity.clear();
+ }
+ }
+
+
+ private static class Scheduler implements Runnable {
+
+ private WeakReference mPendingTracker = new WeakReference<>(null);
+ private MainThreadExecutor mMainThreadExecutor;
+
+ public synchronized void schedule(RecentsActivityTracker tracker) {
+ mPendingTracker = new WeakReference<>(tracker);
+ if (mMainThreadExecutor == null) {
+ mMainThreadExecutor = new MainThreadExecutor();
+ }
+ mMainThreadExecutor.execute(this);
+ }
+
+ @Override
+ public void run() {
+ RecentsActivity activity = sCurrentActivity.get();
+ if (activity != null) {
+ initIfPending(activity, activity.isStarted());
+ }
+ }
+
+ public synchronized boolean initIfPending(RecentsActivity activity, boolean alreadyOnHome) {
+ RecentsActivityTracker tracker = mPendingTracker.get();
+ if (tracker != null) {
+ if (!tracker.init(activity, alreadyOnHome)) {
+ mPendingTracker.clear();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized boolean clearReference(RecentsActivityTracker tracker) {
+ if (mPendingTracker.get() == tracker) {
+ mPendingTracker.clear();
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
new file mode 100644
index 0000000000..34d42ac927
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.UiThreadHelper;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Wrapper around RecentsAnimationController to help with some synchronization
+ */
+public class RecentsAnimationWrapper {
+
+ // A list of callbacks to run when we receive the recents animation target. There are different
+ // than the state callbacks as these run on the current worker thread.
+ private final ArrayList mCallbacks = new ArrayList<>();
+
+ public RemoteAnimationTargetSet targetSet;
+
+ private RecentsAnimationControllerCompat mController;
+ private boolean mInputConsumerEnabled = false;
+ private boolean mBehindSystemBars = true;
+ private boolean mSplitScreenMinimized = false;
+
+ private final ExecutorService mExecutorService =
+ new LooperExecutor(UiThreadHelper.getBackgroundLooper());
+
+ public synchronized void setController(
+ RecentsAnimationControllerCompat controller, RemoteAnimationTargetSet targetSet) {
+ TraceHelper.partitionSection("RecentsController", "Set controller " + controller);
+ this.mController = controller;
+ this.targetSet = targetSet;
+
+ if (mInputConsumerEnabled) {
+ enableInputConsumer();
+ }
+
+ if (!mCallbacks.isEmpty()) {
+ for (Runnable action : new ArrayList<>(mCallbacks)) {
+ action.run();
+ }
+ mCallbacks.clear();
+ }
+ }
+
+ public synchronized void runOnInit(Runnable action) {
+ if (targetSet == null) {
+ mCallbacks.add(action);
+ } else {
+ action.run();
+ }
+ }
+
+ /**
+ * @param onFinishComplete A callback that runs after the animation controller has finished
+ * on the background thread.
+ */
+ public void finish(boolean toHome, Runnable onFinishComplete) {
+ mExecutorService.submit(() -> {
+ RecentsAnimationControllerCompat controller = mController;
+ mController = null;
+ TraceHelper.endSection("RecentsController",
+ "Finish " + controller + ", toHome=" + toHome);
+ if (controller != null) {
+ controller.setInputConsumerEnabled(false);
+ controller.finish(toHome);
+ if (onFinishComplete != null) {
+ onFinishComplete.run();
+ }
+ }
+ });
+ }
+
+ public void enableInputConsumer() {
+ mInputConsumerEnabled = true;
+ if (mInputConsumerEnabled) {
+ mExecutorService.submit(() -> {
+ RecentsAnimationControllerCompat controller = mController;
+ TraceHelper.partitionSection("RecentsController",
+ "Enabling consumer on " + controller);
+ if (controller != null) {
+ controller.setInputConsumerEnabled(true);
+ }
+ });
+ }
+ }
+
+ public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) {
+ if (mBehindSystemBars == behindSystemBars) {
+ return;
+ }
+ mBehindSystemBars = behindSystemBars;
+ mExecutorService.submit(() -> {
+ RecentsAnimationControllerCompat controller = mController;
+ TraceHelper.partitionSection("RecentsController",
+ "Setting behind system bars on " + controller);
+ if (controller != null) {
+ controller.setAnimationTargetsBehindSystemBars(behindSystemBars);
+ }
+ });
+ }
+
+ /**
+ * NOTE: As a workaround for conflicting animations (Launcher animating the task leash, and
+ * SystemUI resizing the docked stack, which resizes the task), we currently only set the
+ * minimized mode, and not the inverse.
+ * TODO: Synchronize the minimize animation with the launcher animation
+ */
+ public void setSplitScreenMinimizedForTransaction(boolean minimized) {
+ if (mSplitScreenMinimized || !minimized) {
+ return;
+ }
+ mSplitScreenMinimized = minimized;
+ mExecutorService.submit(() -> {
+ RecentsAnimationControllerCompat controller = mController;
+ TraceHelper.partitionSection("RecentsController",
+ "Setting minimize dock on " + controller);
+ if (controller != null) {
+ controller.setSplitScreenMinimized(minimized);
+ }
+ });
+ }
+
+ public void hideCurrentInputMethod() {
+ mExecutorService.submit(() -> {
+ RecentsAnimationControllerCompat controller = mController;
+ TraceHelper.partitionSection("RecentsController",
+ "Hiding currentinput method on " + controller);
+ if (controller != null) {
+ controller.hideCurrentInputMethod();
+ }
+ });
+ }
+
+ public RecentsAnimationControllerCompat getController() {
+ return mController;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
new file mode 100644
index 0000000000..9c2c8b3130
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+
+import android.annotation.TargetApi;
+import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.support.annotation.WorkerThread;
+import android.util.Log;
+import android.util.LruCache;
+import android.util.SparseArray;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Preconditions;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.recents.model.IconLoader;
+import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
+import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan.PreloadOptions;
+import com.android.systemui.shared.recents.model.RecentsTaskLoader;
+import com.android.systemui.shared.recents.model.TaskKeyLruCache;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.BackgroundExecutor;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutionException;
+import java.util.function.Consumer;
+
+/**
+ * Singleton class to load and manage recents model.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class RecentsModel extends TaskStackChangeListener {
+ // We do not need any synchronization for this variable as its only written on UI thread.
+ private static RecentsModel INSTANCE;
+
+ public static RecentsModel getInstance(final Context context) {
+ if (INSTANCE == null) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ INSTANCE = new RecentsModel(context.getApplicationContext());
+ } else {
+ try {
+ return new MainThreadExecutor().submit(
+ () -> RecentsModel.getInstance(context)).get();
+ } catch (InterruptedException|ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return INSTANCE;
+ }
+
+ private final SparseArray mCachedAssistData = new SparseArray<>(1);
+ private final ArrayList mAssistDataListeners = new ArrayList<>();
+
+ private final Context mContext;
+ private final RecentsTaskLoader mRecentsTaskLoader;
+ private final MainThreadExecutor mMainThreadExecutor;
+
+ private RecentsTaskLoadPlan mLastLoadPlan;
+ private int mLastLoadPlanId;
+ private int mTaskChangeId;
+ private ISystemUiProxy mSystemUiProxy;
+ private boolean mClearAssistCacheOnStackChange = true;
+ private final boolean mIsLowRamDevice;
+ private boolean mPreloadTasksInBackground;
+ private final AccessibilityManager mAccessibilityManager;
+
+ private RecentsModel(Context context) {
+ mContext = context;
+
+ ActivityManager activityManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ mIsLowRamDevice = activityManager.isLowRamDevice();
+ mMainThreadExecutor = new MainThreadExecutor();
+
+ Resources res = context.getResources();
+ mRecentsTaskLoader = new RecentsTaskLoader(mContext,
+ res.getInteger(R.integer.config_recentsMaxThumbnailCacheSize),
+ res.getInteger(R.integer.config_recentsMaxIconCacheSize), 0) {
+
+ @Override
+ protected IconLoader createNewIconLoader(Context context,
+ TaskKeyLruCache iconCache,
+ LruCache activityInfoCache) {
+ return new NormalizedIconLoader(context, iconCache, activityInfoCache);
+ }
+ };
+ mRecentsTaskLoader.startLoader(mContext);
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
+
+ mTaskChangeId = 1;
+ loadTasks(-1, null);
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ }
+
+ public RecentsTaskLoader getRecentsTaskLoader() {
+ return mRecentsTaskLoader;
+ }
+
+ /**
+ * Preloads the task plan
+ * @param taskId The running task id or -1
+ * @param callback The callback to receive the task plan once its complete or null. This is
+ * always called on the UI thread.
+ * @return the request id associated with this call.
+ */
+ public int loadTasks(int taskId, Consumer callback) {
+ final int requestId = mTaskChangeId;
+
+ // Fail fast if nothing has changed.
+ if (mLastLoadPlanId == mTaskChangeId) {
+ if (callback != null) {
+ final RecentsTaskLoadPlan plan = mLastLoadPlan;
+ mMainThreadExecutor.execute(() -> callback.accept(plan));
+ }
+ return requestId;
+ }
+
+ BackgroundExecutor.get().submit(() -> {
+ // Preload the plan
+ RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(mContext);
+ PreloadOptions opts = new PreloadOptions();
+ opts.loadTitles = mAccessibilityManager.isEnabled();
+ loadPlan.preloadPlan(opts, mRecentsTaskLoader, taskId, UserHandle.myUserId());
+ // Set the load plan on UI thread
+ mMainThreadExecutor.execute(() -> {
+ mLastLoadPlan = loadPlan;
+ mLastLoadPlanId = requestId;
+
+ if (callback != null) {
+ callback.accept(loadPlan);
+ }
+ });
+ });
+ return requestId;
+ }
+
+ public void setPreloadTasksInBackground(boolean preloadTasksInBackground) {
+ mPreloadTasksInBackground = preloadTasksInBackground && !mIsLowRamDevice;
+ }
+
+ @Override
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
+ mTaskChangeId++;
+ }
+
+ @Override
+ public void onActivityUnpinned() {
+ mTaskChangeId++;
+ }
+
+ @Override
+ public void onTaskStackChanged() {
+ mTaskChangeId++;
+
+ Preconditions.assertUIThread();
+ if (mClearAssistCacheOnStackChange) {
+ mCachedAssistData.clear();
+ } else {
+ mClearAssistCacheOnStackChange = true;
+ }
+ }
+
+ @Override
+ public void onTaskStackChangedBackground() {
+ int userId = UserHandle.myUserId();
+ if (!mPreloadTasksInBackground || !checkCurrentOrManagedUserId(userId, mContext)) {
+ // TODO: Only register this for the current user
+ return;
+ }
+
+ // Preload a fixed number of task icons/thumbnails in the background
+ ActivityManager.RunningTaskInfo runningTaskInfo =
+ ActivityManagerWrapper.getInstance().getRunningTask();
+ RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(mContext);
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.runningTaskId = runningTaskInfo != null ? runningTaskInfo.id : -1;
+ launchOpts.numVisibleTasks = 2;
+ launchOpts.numVisibleTaskThumbnails = 2;
+ launchOpts.onlyLoadForCache = true;
+ launchOpts.onlyLoadPausedActivities = true;
+ launchOpts.loadThumbnails = true;
+ PreloadOptions preloadOpts = new PreloadOptions();
+ preloadOpts.loadTitles = mAccessibilityManager.isEnabled();
+ plan.preloadPlan(preloadOpts, mRecentsTaskLoader, -1, userId);
+ mRecentsTaskLoader.loadTasks(plan, launchOpts);
+ }
+
+ public boolean isLoadPlanValid(int resultId) {
+ return mTaskChangeId == resultId;
+ }
+
+ public RecentsTaskLoadPlan getLastLoadPlan() {
+ return mLastLoadPlan;
+ }
+
+ public void setSystemUiProxy(ISystemUiProxy systemUiProxy) {
+ mSystemUiProxy = systemUiProxy;
+ }
+
+ public ISystemUiProxy getSystemUiProxy() {
+ return mSystemUiProxy;
+ }
+
+ public void onStart() {
+ mRecentsTaskLoader.startLoader(mContext);
+ mRecentsTaskLoader.getHighResThumbnailLoader().setVisible(true);
+ }
+
+ public void onTrimMemory(int level) {
+ if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+ // We already stop the loader in UI_HIDDEN, so stop the high res loader as well
+ mRecentsTaskLoader.getHighResThumbnailLoader().setVisible(false);
+ }
+ mRecentsTaskLoader.onTrimMemory(level);
+ }
+
+ public void onOverviewShown(boolean fromHome, String tag) {
+ if (mSystemUiProxy == null) {
+ return;
+ }
+ try {
+ mSystemUiProxy.onOverviewShown(fromHome);
+ } catch (RemoteException e) {
+ Log.w(tag,
+ "Failed to notify SysUI of overview shown from " + (fromHome ? "home" : "app")
+ + ": ", e);
+ }
+ }
+
+ @WorkerThread
+ public void preloadAssistData(int taskId, Bundle data) {
+ mMainThreadExecutor.execute(() -> {
+ mCachedAssistData.put(taskId, data);
+ // We expect a stack change callback after the assist data is set. So ignore the
+ // very next stack change callback.
+ mClearAssistCacheOnStackChange = false;
+
+ int count = mAssistDataListeners.size();
+ for (int i = 0; i < count; i++) {
+ mAssistDataListeners.get(i).onAssistDataReceived(taskId);
+ }
+ });
+ }
+
+ public Bundle getAssistData(int taskId) {
+ Preconditions.assertUIThread();
+ return mCachedAssistData.get(taskId);
+ }
+
+ public void addAssistDataListener(AssistDataListener listener) {
+ mAssistDataListeners.add(listener);
+ }
+
+ public void removeAssistDataListener(AssistDataListener listener) {
+ mAssistDataListeners.remove(listener);
+ }
+
+ /**
+ * Callback for receiving assist data
+ */
+ public interface AssistDataListener {
+
+ void onAssistDataReceived(int taskId);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RemoteRunnable.java b/quickstep/src/com/android/quickstep/RemoteRunnable.java
new file mode 100644
index 0000000000..ec7cad4bad
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RemoteRunnable.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+@FunctionalInterface
+public interface RemoteRunnable {
+
+ void run() throws RemoteException;
+
+ static void executeSafely(RemoteRunnable r) {
+ try {
+ r.run();
+ } catch (final RemoteException e) {
+ Log.e("RemoteRunnable", "Error calling remote method", e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
new file mode 100644
index 0000000000..66969c65a5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Preconditions;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+/**
+ * Factory class to create and add an overlays on the TaskView
+ */
+public class TaskOverlayFactory {
+
+ private static TaskOverlayFactory sInstance;
+
+ public static TaskOverlayFactory get(Context context) {
+ Preconditions.assertUIThread();
+ if (sInstance == null) {
+ sInstance = Utilities.getOverrideObject(TaskOverlayFactory.class,
+ context.getApplicationContext(), R.string.task_overlay_factory_class);
+ }
+ return sInstance;
+ }
+
+ public TaskOverlay createOverlay(View thumbnailView) {
+ return new TaskOverlay();
+ }
+
+ public static class TaskOverlay {
+
+ public void setTaskInfo(Task task, ThumbnailData thumbnail, Matrix matrix) { }
+
+ public void reset() { }
+
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
new file mode 100644
index 0000000000..f82ff8c535
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.View;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.util.InstantAppResolver;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskThumbnailView;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
+import com.android.systemui.shared.recents.view.RecentsTransition;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Represents a system shortcut that can be shown for a recent task.
+ */
+public class TaskSystemShortcut extends SystemShortcut {
+
+ private static final String TAG = "TaskSystemShortcut";
+
+ protected T mSystemShortcut;
+
+ protected TaskSystemShortcut(T systemShortcut) {
+ super(systemShortcut.iconResId, systemShortcut.labelResId);
+ mSystemShortcut = systemShortcut;
+ }
+
+ protected TaskSystemShortcut(int iconResId, int labelResId) {
+ super(iconResId, labelResId);
+ }
+
+ @Override
+ public View.OnClickListener getOnClickListener(
+ BaseDraggingActivity activity, ItemInfo itemInfo) {
+ return null;
+ }
+
+ public View.OnClickListener getOnClickListener(BaseDraggingActivity activity, TaskView view) {
+ Task task = view.getTask();
+
+ ShortcutInfo dummyInfo = new ShortcutInfo();
+ dummyInfo.intent = new Intent();
+ ComponentName component = task.getTopComponent();
+ dummyInfo.intent.setComponent(component);
+ dummyInfo.user = UserHandle.of(task.key.userId);
+ dummyInfo.title = TaskUtils.getTitle(activity, task);
+
+ return getOnClickListenerForTask(activity, task, dummyInfo);
+ }
+
+ protected View.OnClickListener getOnClickListenerForTask(
+ BaseDraggingActivity activity, Task task, ItemInfo dummyInfo) {
+ return mSystemShortcut.getOnClickListener(activity, dummyInfo);
+ }
+
+ public static class AppInfo extends TaskSystemShortcut {
+ public AppInfo() {
+ super(new SystemShortcut.AppInfo());
+ }
+ }
+
+ public static class SplitScreen extends TaskSystemShortcut {
+
+ private Handler mHandler;
+
+ public SplitScreen() {
+ super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
+ mHandler = new Handler(Looper.getMainLooper());
+ }
+
+ @Override
+ public View.OnClickListener getOnClickListener(
+ BaseDraggingActivity activity, TaskView taskView) {
+ if (activity.getDeviceProfile().isMultiWindowMode) {
+ return null;
+ }
+ final Task task = taskView.getTask();
+ final int taskId = task.key.id;
+ if (!task.isDockable) {
+ return null;
+ }
+ final RecentsView recentsView = activity.getOverviewPanel();
+
+ final TaskThumbnailView thumbnailView = taskView.getThumbnail();
+ return (v -> {
+ final View.OnLayoutChangeListener onLayoutChangeListener =
+ new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int l, int t, int r, int b,
+ int oldL, int oldT, int oldR, int oldB) {
+ taskView.getRootView().removeOnLayoutChangeListener(this);
+ recentsView.removeIgnoreResetTask(taskView);
+
+ // Start animating in the side pages once launcher has been resized
+ recentsView.dismissTask(taskView, false, false);
+ }
+ };
+
+ final DeviceProfile.OnDeviceProfileChangeListener onDeviceProfileChangeListener =
+ new DeviceProfile.OnDeviceProfileChangeListener() {
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ activity.removeOnDeviceProfileChangeListener(this);
+ if (dp.isMultiWindowMode) {
+ taskView.getRootView().addOnLayoutChangeListener(
+ onLayoutChangeListener);
+ }
+ }
+ };
+
+ AbstractFloatingView.closeOpenViews(activity, true,
+ AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
+
+ final int navBarPosition = WindowManagerWrapper.getInstance().getNavBarPosition();
+ if (navBarPosition == WindowManagerWrapper.NAV_BAR_POS_INVALID) {
+ return;
+ }
+ boolean dockTopOrLeft = navBarPosition != WindowManagerWrapper.NAV_BAR_POS_LEFT;
+ if (ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
+ ActivityOptionsCompat.makeSplitScreenOptions(dockTopOrLeft))) {
+ ISystemUiProxy sysUiProxy = RecentsModel.getInstance(activity).getSystemUiProxy();
+ try {
+ sysUiProxy.onSplitScreenInvoked();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
+ return;
+ }
+ activity.getUserEventDispatcher().logActionOnControl(TAP,
+ LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
+ // Add a device profile change listener to kick off animating the side tasks
+ // once we enter multiwindow mode and relayout
+ activity.addOnDeviceProfileChangeListener(onDeviceProfileChangeListener);
+
+ final Runnable animStartedListener = () -> {
+ // Hide the task view and wait for the window to be resized
+ // TODO: Consider animating in launcher and do an in-place start activity
+ // afterwards
+ recentsView.addIgnoreResetTask(taskView);
+ taskView.setAlpha(0f);
+ };
+
+ final int[] position = new int[2];
+ thumbnailView.getLocationOnScreen(position);
+ final int width = (int) (thumbnailView.getWidth() * taskView.getScaleX());
+ final int height = (int) (thumbnailView.getHeight() * taskView.getScaleY());
+ final Rect taskBounds = new Rect(position[0], position[1],
+ position[0] + width, position[1] + height);
+
+ Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
+ taskBounds.width(), taskBounds.height(), thumbnailView, 1f,
+ Color.BLACK);
+ AppTransitionAnimationSpecsFuture future =
+ new AppTransitionAnimationSpecsFuture(mHandler) {
+ @Override
+ public List composeSpecs() {
+ return Collections.singletonList(new AppTransitionAnimationSpecCompat(
+ taskId, thumbnail, taskBounds));
+ }
+ };
+ WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
+ future, animStartedListener, mHandler, true /* scaleUp */);
+ }
+ });
+ }
+ }
+
+ public static class Pin extends TaskSystemShortcut {
+
+ private static final String TAG = Pin.class.getSimpleName();
+
+ private Handler mHandler;
+
+ public Pin() {
+ super(R.drawable.ic_pin, R.string.recent_task_option_pin);
+ mHandler = new Handler(Looper.getMainLooper());
+ }
+
+ @Override
+ public View.OnClickListener getOnClickListener(
+ BaseDraggingActivity activity, TaskView taskView) {
+ ISystemUiProxy sysUiProxy = RecentsModel.getInstance(activity).getSystemUiProxy();
+ if (sysUiProxy == null) {
+ return null;
+ }
+ if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
+ return null;
+ }
+ if (ActivityManagerWrapper.getInstance().isLockToAppActive()) {
+ // We shouldn't be able to pin while an app is locked.
+ return null;
+ }
+ return view -> {
+ Consumer resultCallback = success -> {
+ if (success) {
+ try {
+ sysUiProxy.startScreenPinning(taskView.getTask().key.id);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to start screen pinning: ", e);
+ }
+ } else {
+ taskView.notifyTaskLaunchFailed(TAG);
+ }
+ };
+ taskView.launchTask(true, resultCallback, mHandler);
+ };
+ }
+ }
+
+ public static class Install extends TaskSystemShortcut {
+ public Install() {
+ super(new SystemShortcut.Install());
+ }
+
+ @Override
+ protected View.OnClickListener getOnClickListenerForTask(
+ BaseDraggingActivity activity, Task task, ItemInfo itemInfo) {
+ if (InstantAppResolver.newInstance(activity).isInstantApp(activity,
+ task.getTopComponent().getPackageName())) {
+ return mSystemShortcut.createOnClickListener(activity, itemInfo);
+ }
+ return null;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
new file mode 100644
index 0000000000..2b0c98f939
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
+import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
+import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
+
+import android.animation.ValueAnimator;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.RectF;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.Surface;
+import android.view.View;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.ComponentKey;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.MultiValueUpdateListener;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+
+import java.util.List;
+
+/**
+ * Contains helpful methods for retrieving data from {@link Task}s.
+ */
+public class TaskUtils {
+
+ private static final String TAG = "TaskUtils";
+
+ /**
+ * TODO: remove this once we switch to getting the icon and label from IconCache.
+ */
+ public static CharSequence getTitle(Context context, Task task) {
+ LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(context);
+ UserManagerCompat userManagerCompat = UserManagerCompat.getInstance(context);
+ PackageManager packageManager = context.getPackageManager();
+ UserHandle user = UserHandle.of(task.key.userId);
+ ApplicationInfo applicationInfo = launcherAppsCompat.getApplicationInfo(
+ task.getTopComponent().getPackageName(), 0, user);
+ if (applicationInfo == null) {
+ Log.e(TAG, "Failed to get title for task " + task);
+ return "";
+ }
+ return userManagerCompat.getBadgedLabelForUser(
+ applicationInfo.loadLabel(packageManager), user);
+ }
+
+ public static ComponentKey getComponentKeyForTask(Task.TaskKey taskKey) {
+ return new ComponentKey(taskKey.getComponent(), UserHandle.of(taskKey.userId));
+ }
+
+
+ /**
+ * Try to find a TaskView that corresponds with the component of the launched view.
+ *
+ * If this method returns a non-null TaskView, it will be used in composeRecentsLaunchAnimation.
+ * Otherwise, we will assume we are using a normal app transition, but it's possible that the
+ * opening remote target (which we don't get until onAnimationStart) will resolve to a TaskView.
+ */
+ public static TaskView findTaskViewToLaunch(
+ BaseDraggingActivity activity, View v, RemoteAnimationTargetCompat[] targets) {
+ if (v instanceof TaskView) {
+ return (TaskView) v;
+ }
+ RecentsView recentsView = activity.getOverviewPanel();
+
+ // It's possible that the launched view can still be resolved to a visible task view, check
+ // the task id of the opening task and see if we can find a match.
+ if (v.getTag() instanceof ItemInfo) {
+ ItemInfo itemInfo = (ItemInfo) v.getTag();
+ ComponentName componentName = itemInfo.getTargetComponent();
+ int userId = itemInfo.user.getIdentifier();
+ if (componentName != null) {
+ for (int i = 0; i < recentsView.getChildCount(); i++) {
+ TaskView taskView = recentsView.getPageAt(i);
+ if (recentsView.isTaskViewVisible(taskView)) {
+ Task.TaskKey key = taskView.getTask().key;
+ if (componentName.equals(key.getComponent()) && userId == key.userId) {
+ return taskView;
+ }
+ }
+ }
+ }
+ }
+
+ if (targets == null) {
+ return null;
+ }
+ // Resolve the opening task id
+ int openingTaskId = -1;
+ for (RemoteAnimationTargetCompat target : targets) {
+ if (target.mode == MODE_OPENING) {
+ openingTaskId = target.taskId;
+ break;
+ }
+ }
+
+ // If there is no opening task id, fall back to the normal app icon launch animation
+ if (openingTaskId == -1) {
+ return null;
+ }
+
+ // If the opening task id is not currently visible in overview, then fall back to normal app
+ // icon launch animation
+ TaskView taskView = recentsView.getTaskView(openingTaskId);
+ if (taskView == null || !recentsView.isTaskViewVisible(taskView)) {
+ return null;
+ }
+ return taskView;
+ }
+
+ /**
+ * @return Animator that controls the window of the opening targets for the recents launch
+ * animation.
+ */
+ public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
+ RemoteAnimationTargetCompat[] targets, final ClipAnimationHelper inOutHelper) {
+ final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
+ appAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
+ appAnimator.addUpdateListener(new MultiValueUpdateListener() {
+
+ // Defer fading out the view until after the app window gets faded in
+ final FloatProp mViewAlpha = new FloatProp(1f, 0f, 75, 75, LINEAR);
+ final FloatProp mTaskAlpha = new FloatProp(0f, 1f, 0, 75, LINEAR);
+
+ final RemoteAnimationTargetSet mTargetSet;
+
+ final RectF mThumbnailRect;
+ private Surface mSurface;
+ private long mFrameNumber;
+
+ {
+ mTargetSet = new RemoteAnimationTargetSet(targets, MODE_OPENING);
+ inOutHelper.setTaskTransformCallback((t, app) -> {
+ t.setAlpha(app.leash, mTaskAlpha.value);
+
+ if (!skipViewChanges) {
+ t.deferTransactionUntil(app.leash, mSurface, mFrameNumber);
+ }
+ });
+
+ inOutHelper.prepareAnimation(true /* isOpening */);
+ inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(),
+ mTargetSet.apps.length == 0 ? null : mTargetSet.apps[0]);
+
+ mThumbnailRect = new RectF(inOutHelper.getTargetRect());
+ mThumbnailRect.offset(-v.getTranslationX(), -v.getTranslationY());
+ Utilities.scaleRectFAboutCenter(mThumbnailRect, 1 / v.getScaleX());
+ }
+
+ @Override
+ public void onUpdate(float percent) {
+ mSurface = getSurface(v);
+ mFrameNumber = mSurface != null ? getNextFrameNumber(mSurface) : -1;
+ if (mFrameNumber == -1) {
+ // Booo, not cool! Our surface got destroyed, so no reason to animate anything.
+ Log.w(TAG, "Failed to animate, surface got destroyed.");
+ return;
+ }
+
+ RectF taskBounds = inOutHelper.applyTransform(mTargetSet, 1 - percent);
+ if (!skipViewChanges) {
+ float scale = taskBounds.width() / mThumbnailRect.width();
+ v.setScaleX(scale);
+ v.setScaleY(scale);
+ v.setTranslationX(taskBounds.centerX() - mThumbnailRect.centerX());
+ v.setTranslationY(taskBounds.centerY() - mThumbnailRect.centerY());
+ v.setAlpha(mViewAlpha.value);
+ }
+ }
+ });
+ return appAnimator;
+ }
+
+ public static boolean taskIsATargetWithMode(RemoteAnimationTargetCompat[] targets,
+ int taskId, int mode) {
+ for (RemoteAnimationTargetCompat target : targets) {
+ if (target.mode == mode && target.taskId == taskId) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean checkCurrentOrManagedUserId(int currentUserId, Context context) {
+ if (currentUserId == UserHandle.myUserId()) {
+ return true;
+ }
+ List allUsers = UserManagerCompat.getInstance(context).getUserProfiles();
+ for (int i = allUsers.size() - 1; i >= 0; i--) {
+ if (currentUserId == allUsers.get(i).getIdentifier()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
new file mode 100644
index 0000000000..4cecffa2be
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.support.annotation.IntDef;
+import android.view.Choreographer;
+import android.view.MotionEvent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.function.Consumer;
+
+@TargetApi(Build.VERSION_CODES.O)
+@FunctionalInterface
+public interface TouchConsumer extends Consumer {
+
+ @IntDef(flag = true, value = {
+ INTERACTION_NORMAL,
+ INTERACTION_QUICK_SCRUB
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface InteractionType {}
+ int INTERACTION_NORMAL = 0;
+ int INTERACTION_QUICK_SCRUB = 1;
+
+ default void reset() { }
+
+ default void updateTouchTracking(@InteractionType int interactionType) { }
+
+ default void onQuickScrubEnd() { }
+
+ default void onQuickScrubProgress(float progress) { }
+
+ default void onQuickStep(MotionEvent ev) { }
+
+ default void onCommand(int command) { }
+
+ /**
+ * Called on the binder thread to allow the consumer to process the motion event before it is
+ * posted on a handler thread.
+ */
+ default void preProcessMotionEvent(MotionEvent ev) { }
+
+ default Choreographer getIntrimChoreographer(MotionEventQueue queue) {
+ return null;
+ }
+
+ default void deferInit() { }
+
+ default boolean deferNextEventToMainThread() {
+ return false;
+ }
+
+ default boolean forceToLauncherConsumer() {
+ return false;
+ }
+
+ default void onShowOverviewFromAltTab() {}
+}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
new file mode 100644
index 0000000000..aecb66c77d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -0,0 +1,411 @@
+/*
+ * 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.quickstep;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_POINTER_DOWN;
+import static android.view.MotionEvent.ACTION_POINTER_UP;
+import static android.view.MotionEvent.ACTION_UP;
+import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+
+import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.Service;
+import android.content.Intent;
+import android.graphics.PointF;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Choreographer;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.recents.IOverviewProxy;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
+
+/**
+ * Service connected by system-UI for handling touch interaction.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class TouchInteractionService extends Service {
+
+ private static final SparseArray sMotionEventNames;
+
+ static {
+ sMotionEventNames = new SparseArray<>(3);
+ sMotionEventNames.put(ACTION_DOWN, "ACTION_DOWN");
+ sMotionEventNames.put(ACTION_UP, "ACTION_UP");
+ sMotionEventNames.put(ACTION_CANCEL, "ACTION_CANCEL");
+ }
+
+ public static final int EDGE_NAV_BAR = 1 << 8;
+
+ private static final String TAG = "TouchInteractionService";
+
+ /**
+ * A background thread used for handling UI for another window.
+ */
+ private static HandlerThread sRemoteUiThread;
+
+ private final IBinder mMyBinder = new IOverviewProxy.Stub() {
+
+ @Override
+ public void onPreMotionEvent(@HitTarget int downHitTarget) throws RemoteException {
+ TraceHelper.beginSection("SysUiBinder");
+ setupTouchConsumer(downHitTarget);
+ TraceHelper.partitionSection("SysUiBinder", "Down target " + downHitTarget);
+ }
+
+ @Override
+ public void onMotionEvent(MotionEvent ev) {
+ mEventQueue.queue(ev);
+
+ String name = sMotionEventNames.get(ev.getActionMasked());
+ if (name != null){
+ TraceHelper.partitionSection("SysUiBinder", name);
+ }
+ }
+
+ @Override
+ public void onBind(ISystemUiProxy iSystemUiProxy) {
+ mISystemUiProxy = iSystemUiProxy;
+ mRecentsModel.setSystemUiProxy(mISystemUiProxy);
+ mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
+ }
+
+ @Override
+ public void onQuickScrubStart() {
+ mEventQueue.onQuickScrubStart();
+ TraceHelper.partitionSection("SysUiBinder", "onQuickScrubStart");
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ mEventQueue.onQuickScrubProgress(progress);
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ mEventQueue.onQuickScrubEnd();
+ TraceHelper.endSection("SysUiBinder", "onQuickScrubEnd");
+ }
+
+ @Override
+ public void onOverviewToggle() {
+ mOverviewCommandHelper.onOverviewToggle();
+ }
+
+ @Override
+ public void onOverviewShown(boolean triggeredFromAltTab) {
+ if (triggeredFromAltTab) {
+ setupTouchConsumer(HIT_TARGET_NONE);
+ mEventQueue.onOverviewShownFromAltTab();
+ } else {
+ mOverviewCommandHelper.onOverviewShown();
+ }
+ }
+
+ @Override
+ public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ if (triggeredFromAltTab && !triggeredFromHomeKey) {
+ // onOverviewShownFromAltTab initiates quick scrub. Ending it here.
+ mEventQueue.onQuickScrubEnd();
+ }
+ }
+
+ @Override
+ public void onQuickStep(MotionEvent motionEvent) {
+ mEventQueue.onQuickStep(motionEvent);
+ TraceHelper.endSection("SysUiBinder", "onQuickStep");
+
+ }
+
+ @Override
+ public void onTip(int actionType, int viewType) {
+ mOverviewCommandHelper.onTip(actionType, viewType);
+ }
+ };
+
+ private final TouchConsumer mNoOpTouchConsumer = (ev) -> {};
+
+ private static boolean sConnected = false;
+
+ public static boolean isConnected() {
+ return sConnected;
+ }
+
+ private ActivityManagerWrapper mAM;
+ private RecentsModel mRecentsModel;
+ private MotionEventQueue mEventQueue;
+ private MainThreadExecutor mMainThreadExecutor;
+ private ISystemUiProxy mISystemUiProxy;
+ private OverviewCommandHelper mOverviewCommandHelper;
+ private OverviewInteractionState mOverviewInteractionState;
+ private OverviewCallbacks mOverviewCallbacks;
+
+ private Choreographer mMainThreadChoreographer;
+ private Choreographer mBackgroundThreadChoreographer;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mAM = ActivityManagerWrapper.getInstance();
+ mRecentsModel = RecentsModel.getInstance(this);
+ mRecentsModel.setPreloadTasksInBackground(true);
+ mMainThreadExecutor = new MainThreadExecutor();
+ mOverviewCommandHelper = new OverviewCommandHelper(this);
+ mMainThreadChoreographer = Choreographer.getInstance();
+ mEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer);
+ mOverviewInteractionState = OverviewInteractionState.getInstance(this);
+ mOverviewCallbacks = OverviewCallbacks.get(this);
+
+ sConnected = true;
+
+ // Temporarily disable model preload
+ // new ModelPreload().start(this);
+ initBackgroundChoreographer();
+ }
+
+ @Override
+ public void onDestroy() {
+ mOverviewCommandHelper.onDestroy();
+ sConnected = false;
+ super.onDestroy();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.d(TAG, "Touch service connected");
+ return mMyBinder;
+ }
+
+ private void setupTouchConsumer(@HitTarget int downHitTarget) {
+ mEventQueue.reset();
+ TouchConsumer oldConsumer = mEventQueue.getConsumer();
+ if (oldConsumer.deferNextEventToMainThread()) {
+ mEventQueue = new MotionEventQueue(mMainThreadChoreographer,
+ new DeferredTouchConsumer((v) -> getCurrentTouchConsumer(downHitTarget,
+ oldConsumer.forceToLauncherConsumer(), v)));
+ mEventQueue.deferInit();
+ } else {
+ mEventQueue = new MotionEventQueue(
+ mMainThreadChoreographer, getCurrentTouchConsumer(downHitTarget, false, null));
+ }
+ }
+
+ private TouchConsumer getCurrentTouchConsumer(
+ @HitTarget int downHitTarget, boolean forceToLauncher, VelocityTracker tracker) {
+ RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
+
+ if (runningTaskInfo == null && !forceToLauncher) {
+ return mNoOpTouchConsumer;
+ } else if (forceToLauncher ||
+ runningTaskInfo.topActivity.equals(mOverviewCommandHelper.overviewComponent)) {
+ return getOverviewConsumer();
+ } else {
+ if (tracker == null) {
+ tracker = VelocityTracker.obtain();
+ }
+ return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
+ mOverviewCommandHelper.overviewIntent,
+ mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor,
+ mBackgroundThreadChoreographer, downHitTarget, mOverviewCallbacks,
+ tracker);
+ }
+ }
+
+ private TouchConsumer getOverviewConsumer() {
+ ActivityControlHelper activityHelper = mOverviewCommandHelper.getActivityControlHelper();
+ BaseDraggingActivity activity = activityHelper.getCreatedActivity();
+ if (activity == null) {
+ return mNoOpTouchConsumer;
+ }
+ return new OverviewTouchConsumer(activityHelper, activity);
+ }
+
+ private static class OverviewTouchConsumer
+ implements TouchConsumer {
+
+ private final ActivityControlHelper mActivityHelper;
+ private final T mActivity;
+ private final BaseDragLayer mTarget;
+ private final int[] mLocationOnScreen = new int[2];
+ private final PointF mDownPos = new PointF();
+ private final int mTouchSlop;
+ private final QuickScrubController mQuickScrubController;
+
+ private boolean mTrackingStarted = false;
+ private boolean mInvalidated = false;
+
+ private float mLastProgress = 0;
+ private boolean mStartPending = false;
+ private boolean mEndPending = false;
+
+ OverviewTouchConsumer(ActivityControlHelper activityHelper, T activity) {
+ mActivityHelper = activityHelper;
+ mActivity = activity;
+ mTarget = activity.getDragLayer();
+ mTouchSlop = ViewConfiguration.get(mTarget.getContext()).getScaledTouchSlop();
+
+ mQuickScrubController = mActivity.getOverviewPanel()
+ .getQuickScrubController();
+ }
+
+ @Override
+ public void accept(MotionEvent ev) {
+ if (mInvalidated) {
+ return;
+ }
+ int action = ev.getActionMasked();
+ if (action == ACTION_DOWN) {
+ mTrackingStarted = false;
+ mDownPos.set(ev.getX(), ev.getY());
+ } else if (!mTrackingStarted) {
+ switch (action) {
+ case ACTION_POINTER_UP:
+ case ACTION_POINTER_DOWN:
+ if (!mTrackingStarted) {
+ mInvalidated = true;
+ }
+ break;
+ case ACTION_MOVE: {
+ float displacement = ev.getY() - mDownPos.y;
+ if (Math.abs(displacement) >= mTouchSlop) {
+ mTarget.getLocationOnScreen(mLocationOnScreen);
+
+ // Send a down event only when mTouchSlop is crossed.
+ MotionEvent down = MotionEvent.obtain(ev);
+ down.setAction(ACTION_DOWN);
+ sendEvent(down);
+ down.recycle();
+ mTrackingStarted = true;
+ }
+ }
+ }
+ }
+
+ if (mTrackingStarted) {
+ sendEvent(ev);
+ }
+
+ if (action == ACTION_UP || action == ACTION_CANCEL) {
+ mInvalidated = true;
+ }
+ }
+
+ private void sendEvent(MotionEvent ev) {
+ int flags = ev.getEdgeFlags();
+ ev.setEdgeFlags(flags | EDGE_NAV_BAR);
+ ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
+ if (!mTrackingStarted) {
+ mTarget.onInterceptTouchEvent(ev);
+ }
+ mTarget.onTouchEvent(ev);
+ ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
+ ev.setEdgeFlags(flags);
+ }
+
+ @Override
+ public void onQuickStep(MotionEvent ev) {
+ if (mInvalidated) {
+ return;
+ }
+ OverviewCallbacks.get(mActivity).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ }
+
+ @Override
+ public void updateTouchTracking(int interactionType) {
+ if (mInvalidated) {
+ return;
+ }
+ if (interactionType == INTERACTION_QUICK_SCRUB) {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mInvalidated = true;
+ return;
+ }
+ OverviewCallbacks.get(mActivity).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+
+ mStartPending = true;
+ Runnable action = () -> {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mInvalidated = true;
+ return;
+ }
+ mActivityHelper.onQuickInteractionStart(mActivity, null, true);
+ mQuickScrubController.onQuickScrubProgress(mLastProgress);
+ mStartPending = false;
+
+ if (mEndPending) {
+ mQuickScrubController.onQuickScrubEnd();
+ mEndPending = false;
+ }
+ };
+
+ mActivityHelper.executeOnWindowAvailable(mActivity, action);
+ }
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ if (mInvalidated) {
+ return;
+ }
+ if (mStartPending) {
+ mEndPending = true;
+ } else {
+ mQuickScrubController.onQuickScrubEnd();
+ }
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ mLastProgress = progress;
+ if (mInvalidated || mStartPending) {
+ return;
+ }
+ mQuickScrubController.onQuickScrubProgress(progress);
+ }
+
+ }
+
+ private void initBackgroundChoreographer() {
+ if (sRemoteUiThread == null) {
+ sRemoteUiThread = new HandlerThread("remote-ui");
+ sRemoteUiThread.start();
+ }
+ new Handler(sRemoteUiThread.getLooper()).post(() ->
+ mBackgroundThreadChoreographer = Choreographer.getInstance());
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
new file mode 100644
index 0000000000..b1663b169a
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -0,0 +1,961 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
+import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
+import static com.android.launcher3.Utilities.postAsyncCallback;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION;
+import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
+import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.support.annotation.AnyThread;
+import android.support.annotation.UiThread;
+import android.support.annotation.WorkerThread;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewTreeObserver.OnDrawListener;
+import android.view.WindowManager;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.TraceHelper;
+import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
+import com.android.quickstep.ActivityControlHelper.AnimationFactory;
+import com.android.quickstep.ActivityControlHelper.LayoutListener;
+import com.android.quickstep.TouchConsumer.InteractionType;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.TransformedRect;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputConsumerController;
+import com.android.systemui.shared.system.LatencyTrackerCompat;
+import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.WindowCallbacksCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.util.StringJoiner;
+
+@TargetApi(Build.VERSION_CODES.O)
+public class WindowTransformSwipeHandler {
+ private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
+ private static final boolean DEBUG_STATES = false;
+
+ // Launcher UI related states
+ private static final int STATE_LAUNCHER_PRESENT = 1 << 0;
+ private static final int STATE_LAUNCHER_STARTED = 1 << 1;
+ private static final int STATE_LAUNCHER_DRAWN = 1 << 2;
+ private static final int STATE_ACTIVITY_MULTIPLIER_COMPLETE = 1 << 3;
+
+ // Internal initialization states
+ private static final int STATE_APP_CONTROLLER_RECEIVED = 1 << 4;
+
+ // Interaction finish states
+ private static final int STATE_SCALED_CONTROLLER_RECENTS = 1 << 5;
+ private static final int STATE_SCALED_CONTROLLER_APP = 1 << 6;
+
+ private static final int STATE_HANDLER_INVALIDATED = 1 << 7;
+ private static final int STATE_GESTURE_STARTED = 1 << 8;
+ private static final int STATE_GESTURE_CANCELLED = 1 << 9;
+ private static final int STATE_GESTURE_COMPLETED = 1 << 10;
+
+ // States for quick switch/scrub
+ private static final int STATE_CURRENT_TASK_FINISHED = 1 << 11;
+ private static final int STATE_QUICK_SCRUB_START = 1 << 12;
+ private static final int STATE_QUICK_SCRUB_END = 1 << 13;
+
+ private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14;
+ private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15;
+
+ private static final int STATE_RESUME_LAST_TASK = 1 << 16;
+
+ private static final int LAUNCHER_UI_STATES =
+ STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
+ | STATE_LAUNCHER_STARTED;
+
+ private static final int LONG_SWIPE_ENTER_STATE =
+ STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_STARTED
+ | STATE_APP_CONTROLLER_RECEIVED;
+
+ private static final int LONG_SWIPE_START_STATE =
+ STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_STARTED
+ | STATE_APP_CONTROLLER_RECEIVED | STATE_SCREENSHOT_CAPTURED;
+
+ // For debugging, keep in sync with above states
+ private static final String[] STATES = new String[] {
+ "STATE_LAUNCHER_PRESENT",
+ "STATE_LAUNCHER_STARTED",
+ "STATE_LAUNCHER_DRAWN",
+ "STATE_ACTIVITY_MULTIPLIER_COMPLETE",
+ "STATE_APP_CONTROLLER_RECEIVED",
+ "STATE_SCALED_CONTROLLER_RECENTS",
+ "STATE_SCALED_CONTROLLER_APP",
+ "STATE_HANDLER_INVALIDATED",
+ "STATE_GESTURE_STARTED",
+ "STATE_GESTURE_CANCELLED",
+ "STATE_GESTURE_COMPLETED",
+ "STATE_CURRENT_TASK_FINISHED",
+ "STATE_QUICK_SCRUB_START",
+ "STATE_QUICK_SCRUB_END",
+ "STATE_CAPTURE_SCREENSHOT",
+ "STATE_SCREENSHOT_CAPTURED",
+ "STATE_RESUME_LAST_TASK",
+ };
+
+ public static final long MAX_SWIPE_DURATION = 350;
+ public static final long MIN_SWIPE_DURATION = 80;
+
+ private static final float MIN_PROGRESS_FOR_OVERVIEW = 0.5f;
+ private static final float SWIPE_DURATION_MULTIPLIER =
+ Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW));
+
+ private final ClipAnimationHelper mClipAnimationHelper = new ClipAnimationHelper();
+
+ protected Runnable mGestureEndCallback;
+ protected boolean mIsGoingToHome;
+ private DeviceProfile mDp;
+ private int mTransitionDragLength;
+
+ // Shift in the range of [0, 1].
+ // 0 => preview snapShot is completely visible, and hotseat is completely translated down
+ // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
+ // visible.
+ private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
+
+ private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
+
+ // An increasing identifier per single instance of OtherActivityTouchConsumer. Generally one
+ // instance of OtherActivityTouchConsumer will only have one swipe handle, but sometimes we can
+ // end up with multiple handlers if we get recents command in the middle of a swipe gesture.
+ // This is used to match the corresponding activity manager callbacks in
+ // OtherActivityTouchConsumer
+ public final int id;
+ private final Context mContext;
+ private final ActivityControlHelper mActivityControlHelper;
+ private final ActivityInitListener mActivityInitListener;
+
+ private final int mRunningTaskId;
+ private final RunningTaskInfo mRunningTaskInfo;
+ private ThumbnailData mTaskSnapshot;
+
+ private MultiStateCallback mStateCallback;
+ private AnimatorPlaybackController mLauncherTransitionController;
+
+ private T mActivity;
+ private LayoutListener mLayoutListener;
+ private RecentsView mRecentsView;
+ private QuickScrubController mQuickScrubController;
+ private AnimationFactory mAnimationFactory = (t, i) -> { };
+
+ private Runnable mLauncherDrawnCallback;
+
+ private boolean mWasLauncherAlreadyVisible;
+
+ private boolean mGestureStarted;
+ private int mLogAction = Touch.SWIPE;
+ private float mCurrentQuickScrubProgress;
+ private boolean mQuickScrubBlocked;
+
+ private @InteractionType int mInteractionType = INTERACTION_NORMAL;
+
+ private InputConsumerController mInputConsumer =
+ InputConsumerController.getRecentsAnimationInputConsumer();
+
+ private final RecentsAnimationWrapper mRecentsAnimationWrapper = new RecentsAnimationWrapper();
+
+ private final long mTouchTimeMs;
+ private long mLauncherFrameDrawnTime;
+
+ private boolean mBgLongSwipeMode = false;
+ private boolean mUiLongSwipeMode = false;
+ private float mLongSwipeDisplacement = 0;
+ private LongSwipeHelper mLongSwipeController;
+
+ WindowTransformSwipeHandler(int id, RunningTaskInfo runningTaskInfo, Context context,
+ long touchTimeMs, ActivityControlHelper controller) {
+ this.id = id;
+ mContext = context;
+ mRunningTaskInfo = runningTaskInfo;
+ mRunningTaskId = runningTaskInfo.id;
+ mTouchTimeMs = touchTimeMs;
+ mActivityControlHelper = controller;
+ mActivityInitListener = mActivityControlHelper
+ .createActivityInitListener(this::onActivityInit);
+
+ initStateCallbacks();
+ // Register the input consumer on the UI thread, to ensure that it runs after any pending
+ // unregister calls
+ executeOnUiThread(mInputConsumer::registerInputConsumer);
+ }
+
+ private void initStateCallbacks() {
+ mStateCallback = new MultiStateCallback() {
+ @Override
+ public void setState(int stateFlag) {
+ debugNewState(stateFlag);
+ super.setState(stateFlag);
+ }
+ };
+
+ mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED,
+ this::initializeLauncherAnimationController);
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN,
+ this::launcherFrameDrawn);
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED,
+ this::notifyGestureStartedAsync);
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_STARTED
+ | STATE_GESTURE_CANCELLED,
+ this::resetStateForAnimationCancel);
+
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_APP_CONTROLLER_RECEIVED,
+ this::sendRemoteAnimationsToAnimationFactory);
+
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
+ this::resumeLastTaskForQuickstep);
+ mStateCallback.addCallback(STATE_RESUME_LAST_TASK | STATE_APP_CONTROLLER_RECEIVED,
+ this::resumeLastTask);
+
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
+ | STATE_ACTIVITY_MULTIPLIER_COMPLETE
+ | STATE_CAPTURE_SCREENSHOT,
+ this::switchToScreenshot);
+
+ mStateCallback.addCallback(STATE_SCREENSHOT_CAPTURED | STATE_GESTURE_COMPLETED
+ | STATE_SCALED_CONTROLLER_RECENTS,
+ this::finishCurrentTransitionToHome);
+
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
+ | STATE_ACTIVITY_MULTIPLIER_COMPLETE
+ | STATE_SCALED_CONTROLLER_RECENTS
+ | STATE_CURRENT_TASK_FINISHED
+ | STATE_GESTURE_COMPLETED,
+ this::setupLauncherUiAfterSwipeUpAnimation);
+
+ mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
+ this::invalidateHandlerWithLauncher);
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED
+ | STATE_SCALED_CONTROLLER_APP,
+ this::notifyTransitionCancelled);
+
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
+ | STATE_APP_CONTROLLER_RECEIVED, this::onQuickScrubStart);
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
+ | STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_CURRENT_TASK_FINISHED
+ | STATE_QUICK_SCRUB_END, this::switchToFinalAppAfterQuickScrub);
+
+ mStateCallback.addCallback(LONG_SWIPE_ENTER_STATE, this::checkLongSwipeCanEnter);
+ mStateCallback.addCallback(LONG_SWIPE_START_STATE, this::checkLongSwipeCanStart);
+ }
+
+ private void executeOnUiThread(Runnable action) {
+ if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
+ action.run();
+ } else {
+ postAsyncCallback(mMainThreadHandler, action);
+ }
+ }
+
+ private void setStateOnUiThread(int stateFlag) {
+ if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
+ mStateCallback.setState(stateFlag);
+ } else {
+ postAsyncCallback(mMainThreadHandler, () -> mStateCallback.setState(stateFlag));
+ }
+ }
+
+ private void initTransitionEndpoints(DeviceProfile dp) {
+ mDp = dp;
+
+ TransformedRect tempRect = new TransformedRect();
+ mTransitionDragLength = mActivityControlHelper
+ .getSwipeUpDestinationAndLength(dp, mContext, mInteractionType, tempRect);
+ mClipAnimationHelper.updateTargetRect(tempRect);
+ }
+
+ private long getFadeInDuration() {
+ if (mCurrentShift.getCurrentAnimation() != null) {
+ ObjectAnimator anim = mCurrentShift.getCurrentAnimation();
+ long theirDuration = anim.getDuration() - anim.getCurrentPlayTime();
+
+ // TODO: Find a better heuristic
+ return Math.min(MAX_SWIPE_DURATION, Math.max(theirDuration, MIN_SWIPE_DURATION));
+ } else {
+ return MAX_SWIPE_DURATION;
+ }
+ }
+
+ public void initWhenReady() {
+ mActivityInitListener.register();
+ }
+
+ private boolean onActivityInit(final T activity, Boolean alreadyOnHome) {
+ if (mActivity == activity) {
+ return true;
+ }
+ if (mActivity != null) {
+ // The launcher may have been recreated as a result of device rotation.
+ int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
+ initStateCallbacks();
+ mStateCallback.setState(oldState);
+ mLayoutListener.setHandler(null);
+ }
+ mWasLauncherAlreadyVisible = alreadyOnHome;
+ mActivity = activity;
+ // Override the visibility of the activity until the gesture actually starts and we swipe
+ // up, or until we transition home and the home animation is composed
+ if (alreadyOnHome) {
+ mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ } else {
+ mActivity.addForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ }
+
+ mRecentsView = activity.getOverviewPanel();
+ mQuickScrubController = mRecentsView.getQuickScrubController();
+ mLayoutListener = mActivityControlHelper.createLayoutListener(mActivity);
+
+ mStateCallback.setState(STATE_LAUNCHER_PRESENT);
+ if (alreadyOnHome) {
+ onLauncherStart(activity);
+ } else {
+ activity.setOnStartCallback(this::onLauncherStart);
+ }
+ return true;
+ }
+
+ private void onLauncherStart(final T activity) {
+ if (mActivity != activity) {
+ return;
+ }
+ if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
+ return;
+ }
+
+ mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity,
+ mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
+ AbstractFloatingView.closeAllOpenViews(activity, mWasLauncherAlreadyVisible);
+
+ if (mWasLauncherAlreadyVisible) {
+ mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_DRAWN);
+ } else {
+ TraceHelper.beginSection("WTS-init");
+ View dragLayer = activity.getDragLayer();
+ mActivityControlHelper.getAlphaProperty(activity).setValue(0);
+ dragLayer.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
+
+ @Override
+ public void onDraw() {
+ TraceHelper.endSection("WTS-init", "Launcher frame is drawn");
+ dragLayer.post(() ->
+ dragLayer.getViewTreeObserver().removeOnDrawListener(this));
+ if (activity != mActivity) {
+ return;
+ }
+
+ mStateCallback.setState(STATE_LAUNCHER_DRAWN);
+ }
+ });
+ }
+
+ mRecentsView.showTask(mRunningTaskId);
+ mRecentsView.setRunningTaskHidden(true);
+ mRecentsView.setRunningTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
+ mLayoutListener.open();
+ mStateCallback.setState(STATE_LAUNCHER_STARTED);
+ }
+
+ public void setLauncherOnDrawCallback(Runnable callback) {
+ mLauncherDrawnCallback = callback;
+ }
+
+ private void launcherFrameDrawn() {
+ AlphaProperty property = mActivityControlHelper.getAlphaProperty(mActivity);
+ if (property.getValue() < 1) {
+ if (mGestureStarted) {
+ final MultiStateCallback callback = mStateCallback;
+ ObjectAnimator animator = ObjectAnimator.ofFloat(
+ property, MultiValueAlpha.VALUE, 1);
+ animator.setDuration(getFadeInDuration()).addListener(
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ callback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE);
+ }
+ });
+ animator.start();
+ } else {
+ property.setValue(1);
+ mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE);
+ }
+ }
+ if (mLauncherDrawnCallback != null) {
+ mLauncherDrawnCallback.run();
+ }
+ mLauncherFrameDrawnTime = SystemClock.uptimeMillis();
+ }
+
+ private void sendRemoteAnimationsToAnimationFactory() {
+ mAnimationFactory.onRemoteAnimationReceived(mRecentsAnimationWrapper.targetSet);
+ }
+
+ private void initializeLauncherAnimationController() {
+ mLayoutListener.setHandler(this);
+ buildAnimationController();
+
+ if (LatencyTrackerCompat.isEnabled(mContext)) {
+ LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs));
+ }
+ }
+
+ public void updateInteractionType(@InteractionType int interactionType) {
+ if (mInteractionType != INTERACTION_NORMAL) {
+ throw new IllegalArgumentException(
+ "Can't change interaction type from " + mInteractionType);
+ }
+ if (interactionType != INTERACTION_QUICK_SCRUB) {
+ throw new IllegalArgumentException(
+ "Can't change interaction type to " + interactionType);
+ }
+ mInteractionType = interactionType;
+ mRecentsAnimationWrapper.runOnInit(this::shiftAnimationDestinationForQuickscrub);
+
+ setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
+
+ // Start the window animation without waiting for launcher.
+ animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR);
+ }
+
+ private void shiftAnimationDestinationForQuickscrub() {
+ TransformedRect tempRect = new TransformedRect();
+ mActivityControlHelper
+ .getSwipeUpDestinationAndLength(mDp, mContext, mInteractionType, tempRect);
+ mClipAnimationHelper.updateTargetRect(tempRect);
+
+ float offsetY =
+ mActivityControlHelper.getTranslationYForQuickScrub(tempRect, mDp, mContext);
+ float scale, offsetX;
+ Resources res = mContext.getResources();
+
+ if (ActivityManagerWrapper.getInstance().getRecentTasks(2, UserHandle.myUserId()).size()
+ < 2) {
+ // There are not enough tasks, we don't need to shift
+ offsetX = 0;
+ scale = 1;
+ } else {
+ offsetX = res.getDimensionPixelSize(R.dimen.recents_page_spacing)
+ + tempRect.rect.width();
+ float distanceToReachEdge = mDp.widthPx / 2 + tempRect.rect.width() / 2 +
+ res.getDimensionPixelSize(R.dimen.recents_page_spacing);
+ float interpolation = Math.min(1, offsetX / distanceToReachEdge);
+ scale = TaskView.getCurveScaleForInterpolation(interpolation);
+ }
+ mClipAnimationHelper.offsetTarget(scale, Utilities.isRtl(res) ? -offsetX : offsetX, offsetY,
+ QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR);
+ }
+
+ @WorkerThread
+ public void updateDisplacement(float displacement) {
+ // We are moving in the negative x/y direction
+ displacement = -displacement;
+ if (displacement > mTransitionDragLength) {
+ mCurrentShift.updateValue(1);
+
+ if (!mBgLongSwipeMode) {
+ mBgLongSwipeMode = true;
+ executeOnUiThread(this::onLongSwipeEnabledUi);
+ }
+ mLongSwipeDisplacement = displacement - mTransitionDragLength;
+ executeOnUiThread(this::onLongSwipeDisplacementUpdated);
+ } else {
+ if (mBgLongSwipeMode) {
+ mBgLongSwipeMode = false;
+ executeOnUiThread(this::onLongSwipeDisabledUi);
+ }
+ float translation = Math.max(displacement, 0);
+ float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
+ mCurrentShift.updateValue(shift);
+ }
+ }
+
+ /**
+ * Called by {@link #mLayoutListener} when launcher layout changes
+ */
+ public void buildAnimationController() {
+ initTransitionEndpoints(mActivity.getDeviceProfile());
+ mAnimationFactory.createActivityController(mTransitionDragLength, mInteractionType);
+ }
+
+ private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
+ mLauncherTransitionController = anim;
+ mLauncherTransitionController.dispatchOnStart();
+ mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
+ }
+
+ @WorkerThread
+ private void updateFinalShift() {
+ float shift = mCurrentShift.value;
+
+ RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
+ if (controller != null) {
+ mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, shift);
+
+ // TODO: This logic is spartanic!
+ boolean passedThreshold = shift > 0.12f;
+ mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
+ if (mActivityControlHelper.shouldMinimizeSplitScreen()) {
+ mRecentsAnimationWrapper.setSplitScreenMinimizedForTransaction(passedThreshold);
+ }
+ }
+
+ executeOnUiThread(this::updateFinalShiftUi);
+ }
+
+ private void updateFinalShiftUi() {
+ if (mLauncherTransitionController == null) {
+ return;
+ }
+ mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
+ }
+
+ public void onRecentsAnimationStart(RecentsAnimationControllerCompat controller,
+ RemoteAnimationTargetSet targets, Rect homeContentInsets, Rect minimizedHomeBounds) {
+ LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
+ InvariantDeviceProfile idp = appState == null ?
+ new InvariantDeviceProfile(mContext) : appState.getInvariantDeviceProfile();
+ DeviceProfile dp = idp.getDeviceProfile(mContext);
+ final Rect overviewStackBounds;
+ RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mRunningTaskId);
+
+ if (minimizedHomeBounds != null && runningTaskTarget != null) {
+ overviewStackBounds = mActivityControlHelper
+ .getOverviewWindowBounds(minimizedHomeBounds, runningTaskTarget);
+ dp = dp.getMultiWindowProfile(mContext,
+ new Point(minimizedHomeBounds.width(), minimizedHomeBounds.height()));
+ dp.updateInsets(homeContentInsets);
+ } else {
+ overviewStackBounds = new Rect(0, 0, dp.widthPx, dp.heightPx);
+ // If we are not in multi-window mode, home insets should be same as system insets.
+ Rect insets = new Rect();
+ WindowManagerWrapper.getInstance().getStableInsets(insets);
+ dp = dp.copy(mContext);
+ dp.updateInsets(insets);
+ }
+ dp.updateIsSeascape(mContext.getSystemService(WindowManager.class));
+
+ if (runningTaskTarget != null) {
+ mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
+ }
+ mClipAnimationHelper.prepareAnimation(false /* isOpening */);
+ initTransitionEndpoints(dp);
+
+ mRecentsAnimationWrapper.setController(controller, targets);
+ setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
+ }
+
+ public void onRecentsAnimationCanceled() {
+ mRecentsAnimationWrapper.setController(null, null);
+ mActivityInitListener.unregister();
+ setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
+ }
+
+ public void onGestureStarted() {
+ notifyGestureStartedAsync();
+ setStateOnUiThread(STATE_GESTURE_STARTED);
+ mGestureStarted = true;
+ mRecentsAnimationWrapper.hideCurrentInputMethod();
+ mRecentsAnimationWrapper.enableInputConsumer();
+ }
+
+ /**
+ * Notifies the launcher that the swipe gesture has started. This can be called multiple times
+ * on both background and UI threads
+ */
+ @AnyThread
+ private void notifyGestureStartedAsync() {
+ final T curActivity = mActivity;
+ if (curActivity != null) {
+ // Once the gesture starts, we can no longer transition home through the button, so
+ // reset the force override of the activity visibility
+ mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ }
+ }
+
+ @WorkerThread
+ public void onGestureEnded(float endVelocity) {
+ float flingThreshold = mContext.getResources()
+ .getDimension(R.dimen.quickstep_fling_threshold_velocity);
+ boolean isFling = mGestureStarted && Math.abs(endVelocity) > flingThreshold;
+ setStateOnUiThread(STATE_GESTURE_COMPLETED);
+
+ mLogAction = isFling ? Touch.FLING : Touch.SWIPE;
+
+ if (mBgLongSwipeMode) {
+ executeOnUiThread(() -> onLongSwipeGestureFinishUi(endVelocity, isFling));
+ } else {
+ handleNormalGestureEnd(endVelocity, isFling);
+ }
+ }
+
+ private void handleNormalGestureEnd(float endVelocity, boolean isFling) {
+ long duration = MAX_SWIPE_DURATION;
+ final float endShift;
+ final float startShift;
+ if (!isFling) {
+ endShift = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW && mGestureStarted ? 1 : 0;
+ long expectedDuration = Math.abs(Math.round((endShift - mCurrentShift.value)
+ * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
+ duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
+ startShift = mCurrentShift.value;
+ } else {
+ endShift = endVelocity < 0 ? 1 : 0;
+ float minFlingVelocity = mContext.getResources()
+ .getDimension(R.dimen.quickstep_fling_min_velocity);
+ if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) {
+ float distanceToTravel = (endShift - mCurrentShift.value) * mTransitionDragLength;
+
+ // we want the page's snap velocity to approximately match the velocity at
+ // which the user flings, so we scale the duration by a value near to the
+ // derivative of the scroll interpolator at zero, ie. 2.
+ long baseDuration = Math.round(1000 * Math.abs(distanceToTravel / endVelocity));
+ duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration);
+ }
+ startShift = Utilities.boundToRange(mCurrentShift.value - endVelocity * SINGLE_FRAME_MS
+ / (mTransitionDragLength * 1000), 0, 1);
+ }
+
+ animateToProgress(startShift, endShift, duration, DEACCEL);
+ }
+
+ private void doLogGesture(boolean toLauncher) {
+ final int direction;
+ if (mDp.isVerticalBarLayout()) {
+ direction = (mDp.isSeascape() ^ toLauncher) ? Direction.LEFT : Direction.RIGHT;
+ } else {
+ direction = toLauncher ? Direction.UP : Direction.DOWN;
+ }
+
+ int dstContainerType = toLauncher ? ContainerType.TASKSWITCHER : ContainerType.APP;
+ UserEventDispatcher.newInstance(mContext, mDp).logStateChangeAction(
+ mLogAction, direction,
+ ContainerType.NAVBAR, ContainerType.APP,
+ dstContainerType,
+ 0);
+ }
+
+ /** Animates to the given progress, where 0 is the current app and 1 is overview. */
+ private void animateToProgress(float start, float end, long duration,
+ Interpolator interpolator) {
+ mIsGoingToHome = Float.compare(end, 1) == 0;
+ ObjectAnimator anim = mCurrentShift.animateToValue(start, end).setDuration(duration);
+ anim.setInterpolator(interpolator);
+ anim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ setStateOnUiThread(mIsGoingToHome
+ ? (STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT)
+ : STATE_SCALED_CONTROLLER_APP);
+ }
+ });
+ mRecentsAnimationWrapper.runOnInit(anim::start);
+ }
+
+ @UiThread
+ private void resumeLastTaskForQuickstep() {
+ setStateOnUiThread(STATE_RESUME_LAST_TASK);
+ doLogGesture(false /* toLauncher */);
+ reset();
+ }
+
+ @UiThread
+ private void resumeLastTask() {
+ mRecentsAnimationWrapper.finish(false /* toHome */, null);
+ }
+
+ public void reset() {
+ if (mInteractionType != INTERACTION_QUICK_SCRUB) {
+ // Only invalidate the handler if we are not quick scrubbing, otherwise, it will be
+ // invalidated after the quick scrub ends
+ setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ }
+ }
+
+ private void invalidateHandler() {
+ mCurrentShift.finishAnimation();
+
+ if (mGestureEndCallback != null) {
+ mGestureEndCallback.run();
+ }
+
+ mActivityInitListener.unregister();
+ mInputConsumer.unregisterInputConsumer();
+ mTaskSnapshot = null;
+ }
+
+ private void invalidateHandlerWithLauncher() {
+ mLauncherTransitionController = null;
+ mLayoutListener.finish();
+ mActivityControlHelper.getAlphaProperty(mActivity).setValue(1);
+
+ mRecentsView.setRunningTaskHidden(false);
+ mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, false /* animate */);
+ mQuickScrubController.cancelActiveQuickscrub();
+ }
+
+ private void notifyTransitionCancelled() {
+ mAnimationFactory.onTransitionCancelled();
+ }
+
+ private void resetStateForAnimationCancel() {
+ boolean wasVisible = mWasLauncherAlreadyVisible || mGestureStarted;
+ mActivityControlHelper.onTransitionCancelled(mActivity, wasVisible);
+ }
+
+ public void layoutListenerClosed() {
+ if (mWasLauncherAlreadyVisible && mLauncherTransitionController != null) {
+ mLauncherTransitionController.setPlayFraction(1);
+ }
+ }
+
+ private void switchToScreenshot() {
+ boolean finishTransitionPosted = false;
+ RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
+ if (controller != null) {
+ // Update the screenshot of the task
+ if (mTaskSnapshot == null) {
+ mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
+ }
+ TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
+ mRecentsView.setRunningTaskHidden(false);
+ if (taskView != null) {
+ // Defer finishing the animation until the next launcher frame with the
+ // new thumbnail
+ finishTransitionPosted = new WindowCallbacksCompat(taskView) {
+
+ @Override
+ public void onPostDraw(Canvas canvas) {
+ setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+ detach();
+ }
+ }.attach();
+ }
+ }
+ if (!finishTransitionPosted) {
+ // If we haven't posted a draw callback, set the state immediately.
+ setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+ }
+ }
+
+ private void finishCurrentTransitionToHome() {
+ synchronized (mRecentsAnimationWrapper) {
+ mRecentsAnimationWrapper.finish(true /* toHome */,
+ () -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
+ }
+ }
+
+ private void setupLauncherUiAfterSwipeUpAnimation() {
+ if (mLauncherTransitionController != null) {
+ mLauncherTransitionController.getAnimationPlayer().end();
+ mLauncherTransitionController = null;
+ }
+ mActivityControlHelper.onSwipeUpComplete(mActivity);
+
+ // Animate the first icon.
+ mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
+ mRecentsView.setSwipeDownShouldLaunchApp(true);
+
+ RecentsModel.getInstance(mContext).onOverviewShown(false, TAG);
+
+ doLogGesture(true /* toLauncher */);
+ reset();
+ }
+
+ private void onQuickScrubStart() {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mQuickScrubBlocked = true;
+ setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
+ return;
+ }
+ if (mLauncherTransitionController != null) {
+ mLauncherTransitionController.getAnimationPlayer().end();
+ mLauncherTransitionController = null;
+ }
+
+ mActivityControlHelper.onQuickInteractionStart(mActivity, mRunningTaskInfo, false);
+
+ // Inform the last progress in case we skipped before.
+ mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);
+ }
+
+ private void onFinishedTransitionToQuickScrub() {
+ if (mQuickScrubBlocked) {
+ return;
+ }
+ mQuickScrubController.onFinishedTransitionToQuickScrub();
+ }
+
+ public void onQuickScrubProgress(float progress) {
+ mCurrentQuickScrubProgress = progress;
+ if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null
+ || mQuickScrubBlocked) {
+ return;
+ }
+ mQuickScrubController.onQuickScrubProgress(progress);
+ }
+
+ public void onQuickScrubEnd() {
+ setStateOnUiThread(STATE_QUICK_SCRUB_END);
+ }
+
+ private void switchToFinalAppAfterQuickScrub() {
+ if (mQuickScrubBlocked) {
+ return;
+ }
+ mQuickScrubController.onQuickScrubEnd();
+
+ // Normally this is handled in reset(), but since we are still scrubbing after the
+ // transition into recents, we need to defer the handler invalidation for quick scrub until
+ // after the gesture ends
+ setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ }
+
+ private void debugNewState(int stateFlag) {
+ if (!DEBUG_STATES) {
+ return;
+ }
+
+ int state = mStateCallback.getState();
+ StringJoiner currentStateStr = new StringJoiner(", ", "[", "]");
+ String stateFlagStr = "Unknown-" + stateFlag;
+ for (int i = 0; i < STATES.length; i++) {
+ if ((state & (i << i)) != 0) {
+ currentStateStr.add(STATES[i]);
+ }
+ if (stateFlag == (1 << i)) {
+ stateFlagStr = STATES[i] + " (" + stateFlag + ")";
+ }
+ }
+ Log.d(TAG, "[" + System.identityHashCode(this) + "] Adding " + stateFlagStr + " to "
+ + currentStateStr);
+ }
+
+ public void setGestureEndCallback(Runnable gestureEndCallback) {
+ mGestureEndCallback = gestureEndCallback;
+ }
+
+ // Handling long swipe
+ private void onLongSwipeEnabledUi() {
+ mUiLongSwipeMode = true;
+ checkLongSwipeCanEnter();
+ checkLongSwipeCanStart();
+ }
+
+ private void onLongSwipeDisabledUi() {
+ mUiLongSwipeMode = false;
+
+ if (mLongSwipeController != null) {
+ mLongSwipeController.destroy();
+
+ // Rebuild animations
+ buildAnimationController();
+ }
+ }
+
+ private void onLongSwipeDisplacementUpdated() {
+ if (!mUiLongSwipeMode || mLongSwipeController == null) {
+ return;
+ }
+
+ mLongSwipeController.onMove(mLongSwipeDisplacement);
+ }
+
+ private void checkLongSwipeCanEnter() {
+ if (!mUiLongSwipeMode || !mStateCallback.hasStates(LONG_SWIPE_ENTER_STATE)
+ || !mActivityControlHelper.supportsLongSwipe(mActivity)) {
+ return;
+ }
+
+ // We are entering long swipe mode, make sure the screen shot is captured.
+ mStateCallback.setState(STATE_CAPTURE_SCREENSHOT);
+
+ }
+
+ private void checkLongSwipeCanStart() {
+ if (!mUiLongSwipeMode || !mStateCallback.hasStates(LONG_SWIPE_START_STATE)
+ || !mActivityControlHelper.supportsLongSwipe(mActivity)) {
+ return;
+ }
+
+ RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
+ if (targetSet == null) {
+ // This can happen when cancelAnimation comes on the background thread, while we are
+ // processing the long swipe on the UI thread.
+ return;
+ }
+
+ mLongSwipeController = mActivityControlHelper.getLongSwipeController(
+ mActivity, mRecentsAnimationWrapper.targetSet);
+ onLongSwipeDisplacementUpdated();
+ }
+
+ private void onLongSwipeGestureFinishUi(float velocity, boolean isFling) {
+ if (!mUiLongSwipeMode || mLongSwipeController == null) {
+ mUiLongSwipeMode = false;
+ handleNormalGestureEnd(velocity, isFling);
+ return;
+ }
+ mUiLongSwipeMode = false;
+ finishCurrentTransitionToHome();
+ mLongSwipeController.end(velocity, isFling,
+ () -> setStateOnUiThread(STATE_HANDLER_INVALIDATED));
+
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
new file mode 100644
index 0000000000..9e2de33954
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.fallback;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.quickstep.RecentsActivity;
+import com.android.quickstep.util.LayoutUtils;
+import com.android.quickstep.views.RecentsView;
+
+public class FallbackRecentsView extends RecentsView {
+
+ public FallbackRecentsView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setOverviewStateEnabled(true);
+ getQuickScrubController().onFinishedTransitionToQuickScrub();
+ }
+
+ @Override
+ protected void onAllTasksRemoved() {
+ mActivity.startHome();
+ }
+
+ @Override
+ public void onViewAdded(View child) {
+ super.onViewAdded(child);
+ updateEmptyMessage();
+ }
+
+ @Override
+ public void onViewRemoved(View child) {
+ super.onViewRemoved(child);
+ updateEmptyMessage();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ maybeDrawEmptyMessage(canvas);
+ super.draw(canvas);
+ }
+
+ @Override
+ protected void getTaskSize(DeviceProfile dp, Rect outRect) {
+ LayoutUtils.calculateFallbackTaskSize(getContext(), dp, outRect);
+ }
+
+ @Override
+ public boolean shouldUseMultiWindowTaskSizeStrategy() {
+ // Just use the activity task size for multi-window as well.
+ return false;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java
new file mode 100644
index 0000000000..ca8c2520c4
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.fallback;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.RecentsActivity;
+
+public class RecentsRootView extends BaseDragLayer {
+
+ private final RecentsActivity mActivity;
+
+ private final Point mLastKnownSize = new Point(10, 10);
+
+ public RecentsRootView(Context context, AttributeSet attrs) {
+ super(context, attrs, 1 /* alphaChannelCount */);
+ mActivity = (RecentsActivity) BaseActivity.fromContext(context);
+ setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ }
+
+ public Point getLastKnownSize() {
+ return mLastKnownSize;
+ }
+
+ public void setup() {
+ mControllers = new TouchController[] { new RecentsTaskController(mActivity) };
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Check size changes before the actual measure, to avoid multiple measure calls.
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ if (mLastKnownSize.x != width || mLastKnownSize.y != height) {
+ mLastKnownSize.set(width, height);
+ mActivity.onRootViewSizeChanged();
+ }
+
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ @TargetApi(23)
+ @Override
+ protected boolean fitSystemWindows(Rect insets) {
+ // Update device profile before notifying the children.
+ mActivity.getDeviceProfile().updateInsets(insets);
+ setInsets(insets);
+ return true; // I'll take it from here
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
+ // modifying child layout params.
+ if (!insets.equals(mInsets)) {
+ super.setInsets(insets);
+ }
+ setBackground(insets.top == 0 ? null
+ : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
+ }
+
+ public void dispatchInsets() {
+ mActivity.getDeviceProfile().updateInsets(mInsets);
+ super.setInsets(mInsets);
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
new file mode 100644
index 0000000000..9463cc90f1
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.fallback;
+
+import com.android.launcher3.uioverrides.TaskViewTouchController;
+import com.android.quickstep.RecentsActivity;
+
+public class RecentsTaskController extends TaskViewTouchController {
+
+ public RecentsTaskController(RecentsActivity activity) {
+ super(activity);
+ }
+
+ @Override
+ protected boolean isRecentsInteractive() {
+ return mActivity.hasWindowFocus();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
new file mode 100644
index 0000000000..6dff187ea5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.logging;
+
+import android.content.Context;
+import android.util.Log;
+
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CANCEL_TARGET;
+import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE;
+import static com.android.systemui.shared.system.LauncherEventUtil.DISMISS;
+import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_QUICK_SCRUB_ONBOARDING_TIP;
+import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_SWIPE_UP_ONBOARDING_TIP;
+
+import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.systemui.shared.system.MetricsLoggerCompat;
+
+/**
+ * This class handles AOSP MetricsLogger function calls and logging around
+ * quickstep interactions.
+ */
+@SuppressWarnings("unused")
+public class UserEventDispatcherExtension extends UserEventDispatcher {
+
+ private static final String TAG = "UserEventDispatcher";
+
+ public UserEventDispatcherExtension(Context context) { }
+
+ public void logStateChangeAction(int action, int dir, int srcChildTargetType,
+ int srcParentContainerType, int dstContainerType,
+ int pageIndex) {
+ new MetricsLoggerCompat().visibility(MetricsLoggerCompat.OVERVIEW_ACTIVITY,
+ dstContainerType == LauncherLogProto.ContainerType.TASKSWITCHER);
+ super.logStateChangeAction(action, dir, srcChildTargetType, srcParentContainerType,
+ dstContainerType, pageIndex);
+ }
+
+ public void logActionTip(int actionType, int viewType) {
+ LauncherLogProto.Action action = new LauncherLogProto.Action();
+ LauncherLogProto.Target target = new LauncherLogProto.Target();
+ switch(actionType) {
+ case VISIBLE:
+ action.type = LauncherLogProto.Action.Type.TIP;
+ target.type = LauncherLogProto.Target.Type.CONTAINER;
+ target.containerType = LauncherLogProto.ContainerType.TIP;
+ break;
+ case DISMISS:
+ action.type = LauncherLogProto.Action.Type.TOUCH;
+ action.touch = LauncherLogProto.Action.Touch.TAP;
+ target.type = LauncherLogProto.Target.Type.CONTROL;
+ target.controlType = CANCEL_TARGET;
+ break;
+ default:
+ Log.e(TAG, "Unexpected action type = " + actionType);
+ }
+
+ switch(viewType) {
+ case RECENTS_QUICK_SCRUB_ONBOARDING_TIP:
+ target.tipType = LauncherLogProto.TipType.QUICK_SCRUB_TEXT;
+ break;
+ case RECENTS_SWIPE_UP_ONBOARDING_TIP:
+ target.tipType = LauncherLogProto.TipType.SWIPE_UP_TEXT;
+ break;
+ default:
+ Log.e(TAG, "Unexpected viewType = " + viewType);
+ }
+ LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
+ dispatchUserEvent(event, null);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
new file mode 100644
index 0000000000..a654482f97
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
+
+import android.annotation.TargetApi;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Matrix.ScaleToFit;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Build;
+import android.os.RemoteException;
+import android.support.annotation.Nullable;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.RecentsModel;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskThumbnailView;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.recents.utilities.RectFEvaluator;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.util.function.BiConsumer;
+
+/**
+ * Utility class to handle window clip animation
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class ClipAnimationHelper {
+
+ // The bounds of the source app in device coordinates
+ private final Rect mSourceStackBounds = new Rect();
+ // The insets of the source app
+ private final Rect mSourceInsets = new Rect();
+ // The source app bounds with the source insets applied, in the source app window coordinates
+ private final RectF mSourceRect = new RectF();
+ // The bounds of the task view in launcher window coordinates
+ private final RectF mTargetRect = new RectF();
+ // Set when the final window destination is changed, such as offsetting for quick scrub
+ private final PointF mTargetOffset = new PointF();
+ // The insets to be used for clipping the app window, which can be larger than mSourceInsets
+ // if the aspect ratio of the target is smaller than the aspect ratio of the source rect. In
+ // app window coordinates.
+ private final RectF mSourceWindowClipInsets = new RectF();
+
+ // The bounds of launcher (not including insets) in device coordinates
+ public final Rect mHomeStackBounds = new Rect();
+
+ // The clip rect in source app window coordinates
+ private final Rect mClipRect = new Rect();
+ private final RectFEvaluator mRectFEvaluator = new RectFEvaluator();
+ private final Matrix mTmpMatrix = new Matrix();
+ private final RectF mTmpRectF = new RectF();
+
+ private float mTargetScale = 1f;
+ private float mOffsetScale = 1f;
+ private Interpolator mInterpolator = LINEAR;
+ // We translate y slightly faster than the rest of the animation for quick scrub.
+ private Interpolator mOffsetYInterpolator = LINEAR;
+
+ // Whether to boost the opening animation target layers, or the closing
+ private int mBoostModeTargetLayers = -1;
+ // Wether or not applyTransform has been called yet since prepareAnimation()
+ private boolean mIsFirstFrame = true;
+
+ private BiConsumer mTaskTransformCallback =
+ (t, a) -> { };
+
+ private void updateSourceStack(RemoteAnimationTargetCompat target) {
+ mSourceInsets.set(target.contentInsets);
+ mSourceStackBounds.set(target.sourceContainerBounds);
+
+ // TODO: Should sourceContainerBounds already have this offset?
+ mSourceStackBounds.offsetTo(target.position.x, target.position.y);
+
+ }
+
+ public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) {
+ mHomeStackBounds.set(homeStackBounds);
+ updateSourceStack(target);
+ }
+
+ public void updateTargetRect(TransformedRect targetRect) {
+ mOffsetScale = targetRect.scale;
+ mSourceRect.set(mSourceInsets.left, mSourceInsets.top,
+ mSourceStackBounds.width() - mSourceInsets.right,
+ mSourceStackBounds.height() - mSourceInsets.bottom);
+ mTargetRect.set(targetRect.rect);
+ Utilities.scaleRectFAboutCenter(mTargetRect, targetRect.scale);
+ mTargetRect.offset(mHomeStackBounds.left - mSourceStackBounds.left,
+ mHomeStackBounds.top - mSourceStackBounds.top);
+
+ // Calculate the clip based on the target rect (since the content insets and the
+ // launcher insets may differ, so the aspect ratio of the target rect can differ
+ // from the source rect. The difference between the target rect (scaled to the
+ // source rect) is the amount to clip on each edge.
+ RectF scaledTargetRect = new RectF(mTargetRect);
+ Utilities.scaleRectFAboutCenter(scaledTargetRect,
+ mSourceRect.width() / mTargetRect.width());
+ scaledTargetRect.offsetTo(mSourceRect.left, mSourceRect.top);
+ mSourceWindowClipInsets.set(
+ Math.max(scaledTargetRect.left, 0),
+ Math.max(scaledTargetRect.top, 0),
+ Math.max(mSourceStackBounds.width() - scaledTargetRect.right, 0),
+ Math.max(mSourceStackBounds.height() - scaledTargetRect.bottom, 0));
+ mSourceRect.set(scaledTargetRect);
+ }
+
+ public void prepareAnimation(boolean isOpening) {
+ mIsFirstFrame = true;
+ mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING;
+ }
+
+ public RectF applyTransform(RemoteAnimationTargetSet targetSet, float progress) {
+ RectF currentRect;
+ mTmpRectF.set(mTargetRect);
+ Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale);
+ float offsetYProgress = mOffsetYInterpolator.getInterpolation(progress);
+ progress = mInterpolator.getInterpolation(progress);
+ currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTmpRectF);
+
+ synchronized (mTargetOffset) {
+ // Stay lined up with the center of the target, since it moves for quick scrub.
+ currentRect.offset(mTargetOffset.x * mOffsetScale * progress,
+ mTargetOffset.y * offsetYProgress);
+ }
+
+ mClipRect.left = (int) (mSourceWindowClipInsets.left * progress);
+ mClipRect.top = (int) (mSourceWindowClipInsets.top * progress);
+ mClipRect.right = (int)
+ (mSourceStackBounds.width() - (mSourceWindowClipInsets.right * progress));
+ mClipRect.bottom = (int)
+ (mSourceStackBounds.height() - (mSourceWindowClipInsets.bottom * progress));
+
+ TransactionCompat transaction = new TransactionCompat();
+ if (mIsFirstFrame) {
+ RemoteAnimationProvider.prepareTargetsForFirstFrame(targetSet.unfilteredApps,
+ transaction, mBoostModeTargetLayers);
+ mIsFirstFrame = false;
+ }
+ for (RemoteAnimationTargetCompat app : targetSet.apps) {
+ if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
+ mTmpMatrix.setRectToRect(mSourceRect, currentRect, ScaleToFit.FILL);
+ mTmpMatrix.postTranslate(app.position.x, app.position.y);
+ transaction.setMatrix(app.leash, mTmpMatrix)
+ .setWindowCrop(app.leash, mClipRect);
+ }
+
+ if (app.isNotInRecents
+ || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
+ transaction.setAlpha(app.leash, 1 - progress);
+ }
+
+ mTaskTransformCallback.accept(transaction, app);
+ }
+ transaction.setEarlyWakeup();
+ transaction.apply();
+ return currentRect;
+ }
+
+ public void setTaskTransformCallback
+ (BiConsumer callback) {
+ mTaskTransformCallback = callback;
+ }
+
+ public void offsetTarget(float scale, float offsetX, float offsetY, Interpolator interpolator) {
+ synchronized (mTargetOffset) {
+ mTargetOffset.set(offsetX, offsetY);
+ }
+ mTargetScale = scale;
+ mInterpolator = interpolator;
+ mOffsetYInterpolator = Interpolators.clampToProgress(mInterpolator, 0,
+ QUICK_SCRUB_TRANSLATION_Y_FACTOR);
+ }
+
+ public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) {
+ fromTaskThumbnailView(ttv, rv, null);
+ }
+
+ public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv,
+ @Nullable RemoteAnimationTargetCompat target) {
+ BaseDraggingActivity activity = BaseDraggingActivity.fromContext(ttv.getContext());
+ BaseDragLayer dl = activity.getDragLayer();
+
+ int[] pos = new int[2];
+ dl.getLocationOnScreen(pos);
+ mHomeStackBounds.set(0, 0, dl.getWidth(), dl.getHeight());
+ mHomeStackBounds.offset(pos[0], pos[1]);
+
+ if (target != null) {
+ updateSourceStack(target);
+ } else if (rv.shouldUseMultiWindowTaskSizeStrategy()) {
+ updateStackBoundsToMultiWindowTaskSize(activity);
+ } else {
+ mSourceStackBounds.set(mHomeStackBounds);
+ mSourceInsets.set(activity.getDeviceProfile().getInsets());
+ }
+
+ TransformedRect targetRect = new TransformedRect();
+ dl.getDescendantRectRelativeToSelf(ttv, targetRect.rect);
+ updateTargetRect(targetRect);
+
+ if (target == null) {
+ // Transform the clip relative to the target rect. Only do this in the case where we
+ // aren't applying the insets to the app windows (where the clip should be in target app
+ // space)
+ float scale = mTargetRect.width() / mSourceRect.width();
+ mSourceWindowClipInsets.left = mSourceWindowClipInsets.left * scale;
+ mSourceWindowClipInsets.top = mSourceWindowClipInsets.top * scale;
+ mSourceWindowClipInsets.right = mSourceWindowClipInsets.right * scale;
+ mSourceWindowClipInsets.bottom = mSourceWindowClipInsets.bottom * scale;
+ }
+ }
+
+ private void updateStackBoundsToMultiWindowTaskSize(BaseDraggingActivity activity) {
+ ISystemUiProxy sysUiProxy = RecentsModel.getInstance(activity).getSystemUiProxy();
+ if (sysUiProxy != null) {
+ try {
+ mSourceStackBounds.set(sysUiProxy.getNonMinimizedSplitScreenSecondaryBounds());
+ return;
+ } catch (RemoteException e) {
+ // Use half screen size
+ }
+ }
+
+ // Assume that the task size is half screen size (minus the insets and the divider size)
+ DeviceProfile fullDp = activity.getDeviceProfile().getFullScreenProfile();
+ // Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to
+ // account for system insets
+ int taskWidth = fullDp.availableWidthPx;
+ int taskHeight = fullDp.availableHeightPx;
+ int halfDividerSize = activity.getResources()
+ .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
+
+ Rect insets = new Rect();
+ WindowManagerWrapper.getInstance().getStableInsets(insets);
+ if (fullDp.isLandscape) {
+ taskWidth = taskWidth / 2 - halfDividerSize;
+ } else {
+ taskHeight = taskHeight / 2 - halfDividerSize;
+ }
+
+ // Align the task to bottom left/right edge (closer to nav bar).
+ int left = activity.getDeviceProfile().isSeascape() ? insets.left
+ : (insets.left + fullDp.availableWidthPx - taskWidth);
+ mSourceStackBounds.set(0, 0, taskWidth, taskHeight);
+ mSourceStackBounds.offset(left, insets.top + fullDp.availableHeightPx - taskHeight);
+ }
+
+ public void drawForProgress(TaskThumbnailView ttv, Canvas canvas, float progress) {
+ RectF currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTargetRect);
+ canvas.translate(mSourceStackBounds.left - mHomeStackBounds.left,
+ mSourceStackBounds.top - mHomeStackBounds.top);
+ mTmpMatrix.setRectToRect(mTargetRect, currentRect, ScaleToFit.FILL);
+
+ canvas.concat(mTmpMatrix);
+ canvas.translate(mTargetRect.left, mTargetRect.top);
+
+ float insetProgress = (1 - progress);
+ ttv.drawOnCanvas(canvas,
+ -mSourceWindowClipInsets.left * insetProgress,
+ -mSourceWindowClipInsets.top * insetProgress,
+ ttv.getMeasuredWidth() + mSourceWindowClipInsets.right * insetProgress,
+ ttv.getMeasuredHeight() + mSourceWindowClipInsets.bottom * insetProgress,
+ ttv.getCornerRadius() * progress);
+ }
+
+ public RectF getTargetRect() {
+ return mTargetRect;
+ }
+
+ public RectF getSourceRect() {
+ return mSourceRect;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
new file mode 100644
index 0000000000..ec9c7eaed9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.support.annotation.AnyThread;
+import android.support.annotation.IntDef;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+
+import java.lang.annotation.Retention;
+
+public class LayoutUtils {
+
+ private static final int MULTI_WINDOW_STRATEGY_HALF_SCREEN = 1;
+ private static final int MULTI_WINDOW_STRATEGY_DEVICE_PROFILE = 2;
+
+ @Retention(SOURCE)
+ @IntDef({MULTI_WINDOW_STRATEGY_HALF_SCREEN, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE})
+ private @interface MultiWindowStrategy {}
+
+ public static void calculateLauncherTaskSize(Context context, DeviceProfile dp, Rect outRect) {
+ float extraSpace;
+ if (dp.isVerticalBarLayout()) {
+ extraSpace = 0;
+ } else {
+ extraSpace = dp.hotseatBarSizePx + dp.verticalDragHandleSizePx;
+ }
+ calculateTaskSize(context, dp, extraSpace, MULTI_WINDOW_STRATEGY_HALF_SCREEN, outRect);
+ }
+
+ public static void calculateFallbackTaskSize(Context context, DeviceProfile dp, Rect outRect) {
+ calculateTaskSize(context, dp, 0, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE, outRect);
+ }
+
+ @AnyThread
+ public static void calculateTaskSize(Context context, DeviceProfile dp,
+ float extraVerticalSpace, @MultiWindowStrategy int multiWindowStrategy, Rect outRect) {
+ float taskWidth, taskHeight, paddingHorz;
+ Resources res = context.getResources();
+ Rect insets = dp.getInsets();
+
+ if (dp.isMultiWindowMode) {
+ if (multiWindowStrategy == MULTI_WINDOW_STRATEGY_HALF_SCREEN) {
+ DeviceProfile fullDp = dp.getFullScreenProfile();
+ // Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to
+ // account for system insets
+ taskWidth = fullDp.availableWidthPx;
+ taskHeight = fullDp.availableHeightPx;
+ float halfDividerSize = res.getDimension(R.dimen.multi_window_task_divider_size)
+ / 2;
+
+ if (fullDp.isLandscape) {
+ taskWidth = taskWidth / 2 - halfDividerSize;
+ } else {
+ taskHeight = taskHeight / 2 - halfDividerSize;
+ }
+ } else {
+ // multiWindowStrategy == MULTI_WINDOW_STRATEGY_DEVICE_PROFILE
+ taskWidth = dp.widthPx;
+ taskHeight = dp.heightPx;
+ }
+ paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space);
+ } else {
+ taskWidth = dp.availableWidthPx;
+ taskHeight = dp.availableHeightPx;
+ paddingHorz = res.getDimension(dp.isVerticalBarLayout()
+ ? R.dimen.landscape_task_card_horz_space
+ : R.dimen.portrait_task_card_horz_space);
+ }
+
+ float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
+ float paddingVert = res.getDimension(R.dimen.task_card_vert_space);
+
+ // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
+ // we override the insets ourselves.
+ int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
+ int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom;
+
+ float availableHeight = launcherVisibleHeight
+ - topIconMargin - extraVerticalSpace - paddingVert;
+ float availableWidth = launcherVisibleWidth - paddingHorz;
+
+ float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
+ float outWidth = scale * taskWidth;
+ float outHeight = scale * taskHeight;
+
+ // Center in the visible space
+ float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
+ float y = insets.top + Math.max(topIconMargin,
+ (launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
+ outRect.set(Math.round(x), Math.round(y),
+ Math.round(x + outWidth), Math.round(y + outHeight));
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/MultiValueUpdateListener.java b/quickstep/src/com/android/quickstep/util/MultiValueUpdateListener.java
new file mode 100644
index 0000000000..e798d5cbcc
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/MultiValueUpdateListener.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.animation.ValueAnimator;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+
+/**
+ * Utility class to update multiple values with different interpolators and durations during
+ * the same animation.
+ */
+public abstract class MultiValueUpdateListener implements ValueAnimator.AnimatorUpdateListener {
+
+ private final ArrayList mAllProperties = new ArrayList<>();
+
+ @Override
+ public final void onAnimationUpdate(ValueAnimator animator) {
+ final float percent = animator.getAnimatedFraction();
+ final float currentPlayTime = percent * animator.getDuration();
+
+ for (int i = mAllProperties.size() - 1; i >= 0; i--) {
+ FloatProp prop = mAllProperties.get(i);
+ float time = Math.max(0, currentPlayTime - prop.mDelay);
+ float newPercent = Math.min(1f, time / prop.mDuration);
+ newPercent = prop.mInterpolator.getInterpolation(newPercent);
+ prop.value = prop.mEnd * newPercent + prop.mStart * (1 - newPercent);
+ }
+ onUpdate(percent);
+ }
+
+ public abstract void onUpdate(float percent);
+
+ public final class FloatProp {
+
+ public float value;
+
+ private final float mStart;
+ private final float mEnd;
+ private final float mDelay;
+ private final float mDuration;
+ private final Interpolator mInterpolator;
+
+ public FloatProp(float start, float end, float delay, float duration, Interpolator i) {
+ value = mStart = start;
+ mEnd = end;
+ mDelay = delay;
+ mDuration = duration;
+ mInterpolator = i;
+
+ mAllProperties.add(this);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
new file mode 100644
index 0000000000..bbf223d1ef
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.animation.AnimatorSet;
+import android.app.ActivityOptions;
+import android.os.Handler;
+
+import com.android.launcher3.LauncherAnimationRunner;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+
+@FunctionalInterface
+public interface RemoteAnimationProvider {
+
+ AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targets);
+
+ default ActivityOptions toActivityOptions(Handler handler, long duration) {
+ LauncherAnimationRunner runner = new LauncherAnimationRunner(handler,
+ false /* startAtFrontOfQueue */) {
+
+ @Override
+ public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
+ AnimationResult result) {
+ result.setAnimation(createWindowAnimation(targetCompats));
+ }
+ };
+ return ActivityOptionsCompat.makeRemoteAnimation(
+ new RemoteAnimationAdapterCompat(runner, duration, 0));
+ }
+
+ /**
+ * Prepares the given {@param targets} for a remote animation, and should be called with the
+ * transaction from the first frame of animation.
+ *
+ * @param boostModeTargets The mode indicating which targets to boost in z-order above other
+ * targets.
+ */
+ static void prepareTargetsForFirstFrame(RemoteAnimationTargetCompat[] targets,
+ TransactionCompat t, int boostModeTargets) {
+ for (RemoteAnimationTargetCompat target : targets) {
+ int layer = target.mode == boostModeTargets
+ ? Integer.MAX_VALUE
+ : target.prefixOrderIndex;
+ t.setLayer(target.leash, layer);
+ t.show(target.leash);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java
new file mode 100644
index 0000000000..04b8be58bf
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+
+import java.util.ArrayList;
+
+/**
+ * Holds a collection of RemoteAnimationTargets, filtered by different properties.
+ */
+public class RemoteAnimationTargetSet {
+
+ public final RemoteAnimationTargetCompat[] unfilteredApps;
+ public final RemoteAnimationTargetCompat[] apps;
+
+ public RemoteAnimationTargetSet(RemoteAnimationTargetCompat[] apps, int targetMode) {
+ ArrayList filteredApps = new ArrayList<>();
+ if (apps != null) {
+ for (RemoteAnimationTargetCompat target : apps) {
+ if (target.mode == targetMode) {
+ filteredApps.add(target);
+ }
+ }
+ }
+
+ this.unfilteredApps = apps;
+ this.apps = filteredApps.toArray(new RemoteAnimationTargetCompat[filteredApps.size()]);
+ }
+
+ public RemoteAnimationTargetCompat findTask(int taskId) {
+ for (RemoteAnimationTargetCompat target : apps) {
+ if (target.taskId == taskId) {
+ return target;
+ }
+ }
+ return null;
+ }
+
+ public boolean isAnimatingHome() {
+ for (RemoteAnimationTargetCompat target : apps) {
+ if (target.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
new file mode 100644
index 0000000000..40dd74bbb5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static com.android.quickstep.util.RemoteAnimationProvider.prepareTargetsForFirstFrame;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+
+/**
+ * Animation listener which fades out the closing targets
+ */
+public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener {
+
+ private final RemoteAnimationTargetSet mTarget;
+ private boolean mFirstFrame = true;
+
+ public RemoteFadeOutAnimationListener(RemoteAnimationTargetCompat[] targets) {
+ mTarget = new RemoteAnimationTargetSet(targets, MODE_CLOSING);
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ TransactionCompat t = new TransactionCompat();
+ if (mFirstFrame) {
+ prepareTargetsForFirstFrame(mTarget.unfilteredApps, t, MODE_CLOSING);
+ mFirstFrame = false;
+ }
+
+ float alpha = 1 - valueAnimator.getAnimatedFraction();
+ for (RemoteAnimationTargetCompat app : mTarget.apps) {
+ t.setAlpha(app.leash, alpha);
+ }
+ t.apply();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
new file mode 100644
index 0000000000..48b07a7144
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.util.FloatProperty;
+import android.view.View;
+
+import com.android.launcher3.Utilities;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskThumbnailView;
+import com.android.quickstep.views.TaskView;
+
+public class TaskViewDrawable extends Drawable {
+
+ public static final FloatProperty PROGRESS =
+ new FloatProperty("progress") {
+ @Override
+ public void setValue(TaskViewDrawable taskViewDrawable, float v) {
+ taskViewDrawable.setProgress(v);
+ }
+
+ @Override
+ public Float get(TaskViewDrawable taskViewDrawable) {
+ return taskViewDrawable.mProgress;
+ }
+ };
+
+ /**
+ * The progress at which we play the atomic icon scale animation.
+ */
+ private static final float ICON_SCALE_THRESHOLD = 0.95f;
+
+ private final RecentsView mParent;
+ private final View mIconView;
+ private final int[] mIconPos;
+
+ private final TaskThumbnailView mThumbnailView;
+
+ private final ClipAnimationHelper mClipAnimationHelper;
+
+ private float mProgress = 1;
+ private boolean mPassedIconScaleThreshold;
+ private ValueAnimator mIconScaleAnimator;
+ private float mIconScale;
+
+ public TaskViewDrawable(TaskView tv, RecentsView parent) {
+ mParent = parent;
+ mIconView = tv.getIconView();
+ mIconPos = new int[2];
+ mIconScale = mIconView.getScaleX();
+ Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true);
+
+ mThumbnailView = tv.getThumbnail();
+ mClipAnimationHelper = new ClipAnimationHelper();
+ mClipAnimationHelper.fromTaskThumbnailView(mThumbnailView, parent);
+ }
+
+ public void setProgress(float progress) {
+ mProgress = progress;
+ mParent.invalidate();
+ boolean passedIconScaleThreshold = progress <= ICON_SCALE_THRESHOLD;
+ if (mPassedIconScaleThreshold != passedIconScaleThreshold) {
+ mPassedIconScaleThreshold = passedIconScaleThreshold;
+ animateIconScale(mPassedIconScaleThreshold ? 0 : 1);
+ }
+ }
+
+ private void animateIconScale(float toScale) {
+ if (mIconScaleAnimator != null) {
+ mIconScaleAnimator.cancel();
+ }
+ mIconScaleAnimator = ValueAnimator.ofFloat(mIconScale, toScale);
+ mIconScaleAnimator.addUpdateListener(valueAnimator -> {
+ mIconScale = (float) valueAnimator.getAnimatedValue();
+ if (mProgress > ICON_SCALE_THRESHOLD) {
+ // Speed up the icon scale to ensure it is 1 when progress is 1.
+ float iconProgress = (mProgress - ICON_SCALE_THRESHOLD) / (1 - ICON_SCALE_THRESHOLD);
+ if (iconProgress > mIconScale) {
+ mIconScale = iconProgress;
+ }
+ }
+ invalidateSelf();
+ });
+ mIconScaleAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mIconScaleAnimator = null;
+ }
+ });
+ mIconScaleAnimator.setDuration(TaskView.SCALE_ICON_DURATION);
+ mIconScaleAnimator.start();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.save();
+ canvas.translate(mParent.getScrollX(), mParent.getScrollY());
+ mClipAnimationHelper.drawForProgress(mThumbnailView, canvas, mProgress);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(mIconPos[0], mIconPos[1]);
+ canvas.scale(mIconScale, mIconScale, mIconView.getWidth() / 2, mIconView.getHeight() / 2);
+ mIconView.draw(canvas);
+ canvas.restore();
+ }
+
+ public ClipAnimationHelper getClipAnimationHelper() {
+ return mClipAnimationHelper;
+ }
+
+ @Override
+ public void setAlpha(int i) { }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) { }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/TransformedRect.java b/quickstep/src/com/android/quickstep/util/TransformedRect.java
new file mode 100644
index 0000000000..79f11e405b
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/TransformedRect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.graphics.Rect;
+
+/**
+ * A wrapper around {@link Rect} with additional transformation properties
+ */
+public class TransformedRect {
+
+ public final Rect rect = new Rect();
+ public float scale = 1;
+
+ public void set(TransformedRect transformedRect) {
+ rect.set(transformedRect.rect);
+ scale = transformedRect.scale;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
new file mode 100644
index 0000000000..0025df136d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.views;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.Button;
+
+public class ClearAllButton extends Button {
+ RecentsView mRecentsView;
+
+ public ClearAllButton(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setRecentsView(RecentsView recentsView) {
+ mRecentsView = recentsView;
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setParent(mRecentsView); // Pretend we are a part of the task carousel.
+ }
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+ if (focused) {
+ mRecentsView.revealClearAllButton();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java
new file mode 100644
index 0000000000..c359966df4
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/IconView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
+ * when the drawable changes.
+ */
+public class IconView extends View {
+
+ private Drawable mDrawable;
+
+ public IconView(Context context) {
+ super(context);
+ }
+
+ public IconView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public IconView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void setDrawable(Drawable d) {
+ if (mDrawable != null) {
+ mDrawable.setCallback(null);
+ }
+ mDrawable = d;
+ if (mDrawable != null) {
+ mDrawable.setCallback(this);
+ mDrawable.setBounds(0, 0, getWidth(), getHeight());
+ }
+ invalidate();
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ if (mDrawable != null) {
+ mDrawable.setBounds(0, 0, w, h);
+ }
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who) || who == mDrawable;
+ }
+
+ @Override
+ protected void drawableStateChanged() {
+ super.drawableStateChanged();
+
+ final Drawable drawable = mDrawable;
+ if (drawable != null && drawable.isStateful()
+ && drawable.setState(getDrawableState())) {
+ invalidateDrawable(drawable);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mDrawable != null) {
+ mDrawable.draw(canvas);
+ }
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java b/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
new file mode 100644
index 0000000000..c149de54f0
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
+import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
+
+import android.graphics.Rect;
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
+import com.android.quickstep.ActivityControlHelper.LayoutListener;
+import com.android.quickstep.WindowTransformSwipeHandler;
+
+/**
+ * Floating view which shows the task snapshot allowing it to be dragged and placed.
+ */
+public class LauncherLayoutListener extends AbstractFloatingView
+ implements Insettable, LayoutListener {
+
+ private final Launcher mLauncher;
+ private WindowTransformSwipeHandler mHandler;
+
+ public LauncherLayoutListener(Launcher launcher) {
+ super(launcher, null);
+ mLauncher = launcher;
+ setVisibility(INVISIBLE);
+
+ // For the duration of the gesture, lock the screen orientation to ensure that we do not
+ // rotate mid-quickscrub
+ launcher.getRotationHelper().setStateHandlerRequest(REQUEST_LOCK);
+ }
+
+ @Override
+ public void setHandler(WindowTransformSwipeHandler handler) {
+ mHandler = handler;
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ if (mHandler != null) {
+ mHandler.buildAnimationController();
+ }
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ @Override
+ protected void handleClose(boolean animate) {
+ if (mIsOpen) {
+ mIsOpen = false;
+ // We don't support animate.
+ mLauncher.getDragLayer().removeView(this);
+
+ if (mHandler != null) {
+ mHandler.layoutListenerClosed();
+ }
+ }
+ }
+
+ @Override
+ public void open() {
+ if (!mIsOpen) {
+ mLauncher.getDragLayer().addView(this);
+ mIsOpen = true;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(1, 1);
+ }
+
+ @Override
+ public void logActionCommand(int command) {
+ // We should probably log the weather
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_QUICKSTEP_PREVIEW) != 0;
+ }
+
+ @Override
+ public void finish() {
+ setHandler(null);
+ close(false);
+ mLauncher.getRotationHelper().setStateHandlerRequest(REQUEST_NONE);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
new file mode 100644
index 0000000000..5aca4f3263
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import static com.android.launcher3.LauncherAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
+import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
+
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.view.View;
+import android.view.ViewDebug;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.views.ScrimView;
+import com.android.quickstep.OverviewInteractionState;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.LayoutUtils;
+
+/**
+ * {@link RecentsView} used in Launcher activity
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class LauncherRecentsView extends RecentsView {
+
+ public static final FloatProperty TRANSLATION_Y_FACTOR =
+ new FloatProperty("translationYFactor") {
+
+ @Override
+ public void setValue(LauncherRecentsView view, float v) {
+ view.setTranslationYFactor(v);
+ }
+
+ @Override
+ public Float get(LauncherRecentsView view) {
+ return view.mTranslationYFactor;
+ }
+ };
+
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private float mTranslationYFactor;
+
+ public LauncherRecentsView(Context context) {
+ this(context, null);
+ }
+
+ public LauncherRecentsView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setContentAlpha(0);
+ }
+
+ @Override
+ protected void onAllTasksRemoved() {
+ mActivity.getStateManager().goToState(NORMAL);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ setTranslationYFactor(mTranslationYFactor);
+ }
+
+ public void setTranslationYFactor(float translationFactor) {
+ mTranslationYFactor = translationFactor;
+ setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
+ }
+
+ public float computeTranslationYForFactor(float translationYFactor) {
+ return translationYFactor * (getPaddingBottom() - getPaddingTop());
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ maybeDrawEmptyMessage(canvas);
+ super.draw(canvas);
+ }
+
+ @Override
+ public void onViewAdded(View child) {
+ super.onViewAdded(child);
+ updateEmptyMessage();
+ }
+
+ @Override
+ protected void onTaskStackUpdated() {
+ // Lazily update the empty message only when the task stack is reapplied
+ updateEmptyMessage();
+ }
+
+ /**
+ * Animates adjacent tasks and translate hotseat off screen as well.
+ */
+ @Override
+ public AnimatorSet createAdjacentPageAnimForTaskLaunch(TaskView tv,
+ ClipAnimationHelper helper) {
+ AnimatorSet anim = super.createAdjacentPageAnimForTaskLaunch(tv, helper);
+
+ if (!OverviewInteractionState.getInstance(mActivity).isSwipeUpGestureEnabled()) {
+ // Hotseat doesn't move when opening recents with the button,
+ // so don't animate it here either.
+ return anim;
+ }
+
+ float allAppsProgressOffscreen = ALL_APPS_PROGRESS_OFF_SCREEN;
+ LauncherState state = mActivity.getStateManager().getState();
+ if ((state.getVisibleElements(mActivity) & ALL_APPS_HEADER_EXTRA) != 0) {
+ float maxShiftRange = mActivity.getDeviceProfile().heightPx;
+ float currShiftRange = mActivity.getAllAppsController().getShiftRange();
+ allAppsProgressOffscreen = 1f + (maxShiftRange - currShiftRange) / maxShiftRange;
+ }
+ anim.play(ObjectAnimator.ofFloat(
+ mActivity.getAllAppsController(), ALL_APPS_PROGRESS, allAppsProgressOffscreen));
+
+ ObjectAnimator dragHandleAnim = ObjectAnimator.ofInt(
+ mActivity.findViewById(R.id.scrim_view), ScrimView.DRAG_HANDLE_ALPHA, 0);
+ dragHandleAnim.setInterpolator(Interpolators.ACCEL_2);
+ anim.play(dragHandleAnim);
+
+ return anim;
+ }
+
+ @Override
+ protected void getTaskSize(DeviceProfile dp, Rect outRect) {
+ LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect);
+ }
+
+ @Override
+ protected void onTaskLaunched(boolean success) {
+ if (success) {
+ mActivity.getStateManager().goToState(NORMAL, false /* animate */);
+ } else {
+ LauncherState state = mActivity.getStateManager().getState();
+ mActivity.getAllAppsController().setState(state);
+ }
+ super.onTaskLaunched(success);
+ }
+
+ @Override
+ public boolean shouldUseMultiWindowTaskSizeStrategy() {
+ return mActivity.isInMultiWindowModeCompat();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
new file mode 100644
index 0000000000..d550edcd33
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -0,0 +1,1373 @@
+/*
+ * 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.quickstep.views;
+
+import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
+import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.support.annotation.Nullable;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+import android.util.ArraySet;
+import android.util.AttributeSet;
+import android.util.SparseBooleanArray;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ListView;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.PagedView;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.PropertyListBuilder;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.PendingAnimation;
+import com.android.launcher3.util.Themes;
+import com.android.quickstep.OverviewCallbacks;
+import com.android.quickstep.QuickScrubController;
+import com.android.quickstep.RecentsModel;
+import com.android.quickstep.TaskUtils;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.TaskViewDrawable;
+import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
+import com.android.systemui.shared.recents.model.RecentsTaskLoader;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.TaskStack;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.BackgroundExecutor;
+import com.android.systemui.shared.system.PackageManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * A list of recent tasks.
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public abstract class RecentsView extends PagedView implements Insettable {
+
+ private static final String TAG = RecentsView.class.getSimpleName();
+
+ private final Rect mTempRect = new Rect();
+
+ private static final int DISMISS_TASK_DURATION = 300;
+ // The threshold at which we update the SystemUI flags when animating from the task into the app
+ private static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.6f;
+
+ private static final float[] sTempFloatArray = new float[3];
+
+ protected final T mActivity;
+ private final QuickScrubController mQuickScrubController;
+ private final float mFastFlingVelocity;
+ private final RecentsModel mModel;
+ private final int mTaskTopMargin;
+
+ private final ScrollState mScrollState = new ScrollState();
+ // Keeps track of the previously known visible tasks for purposes of loading/unloading task data
+ private final SparseBooleanArray mHasVisibleTaskData = new SparseBooleanArray();
+
+ private boolean mIsClearAllButtonFullyRevealed;
+
+ /**
+ * TODO: Call reloadIdNeeded in onTaskStackChanged.
+ */
+ private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+ @Override
+ public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
+ updateThumbnail(taskId, snapshot);
+ }
+
+ @Override
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
+ // Check this is for the right user
+ if (!checkCurrentOrManagedUserId(userId, getContext())) {
+ return;
+ }
+
+ // Remove the task immediately from the task list
+ TaskView taskView = getTaskView(taskId);
+ if (taskView != null) {
+ removeView(taskView);
+ }
+ }
+
+ @Override
+ public void onActivityUnpinned() {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
+ // TODO: Re-enable layout transitions for addition of the unpinned task
+ reloadIfNeeded();
+ }
+
+ @Override
+ public void onTaskRemoved(int taskId) {
+ if (!mHandleTaskStackChanges) {
+ return;
+ }
+ BackgroundExecutor.get().submit(() -> {
+ TaskView taskView = getTaskView(taskId);
+ if (taskView == null) {
+ return;
+ }
+ Handler handler = taskView.getHandler();
+ if (handler == null) {
+ return;
+ }
+
+ // TODO: Add callbacks from AM reflecting adding/removing from the recents list, and
+ // remove all these checks
+ Task.TaskKey taskKey = taskView.getTask().key;
+ if (PackageManagerWrapper.getInstance().getActivityInfo(taskKey.getComponent(),
+ taskKey.userId) == null) {
+ // The package was uninstalled
+ handler.post(() ->
+ dismissTask(taskView, true /* animate */, false /* removeTask */));
+ } else {
+ RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(getContext());
+ RecentsTaskLoadPlan.PreloadOptions opts =
+ new RecentsTaskLoadPlan.PreloadOptions();
+ opts.loadTitles = false;
+ loadPlan.preloadPlan(opts, mModel.getRecentsTaskLoader(), -1,
+ UserHandle.myUserId());
+ if (loadPlan.getTaskStack().findTaskWithId(taskId) == null) {
+ // The task was removed from the recents list
+ handler.post(() ->
+ dismissTask(taskView, true /* animate */, false /* removeTask */));
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onPinnedStackAnimationStarted() {
+ // Needed for activities that auto-enter PiP, which will not trigger a remote
+ // animation to be created
+ mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+ }
+ };
+
+ private int mLoadPlanId = -1;
+
+ // Only valid until the launcher state changes to NORMAL
+ private int mRunningTaskId = -1;
+ private boolean mRunningTaskTileHidden;
+ private Task mTmpRunningTask;
+
+ private boolean mRunningTaskIconScaledDown = false;
+
+ private boolean mOverviewStateEnabled;
+ private boolean mHandleTaskStackChanges;
+ private Runnable mNextPageSwitchRunnable;
+ private boolean mSwipeDownShouldLaunchApp;
+
+ private PendingAnimation mPendingAnimation;
+
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private float mContentAlpha = 1;
+
+ // Keeps track of task views whose visual state should not be reset
+ private ArraySet mIgnoreResetTaskViews = new ArraySet<>();
+
+ private View mClearAllButton;
+
+ // Variables for empty state
+ private final Drawable mEmptyIcon;
+ private final CharSequence mEmptyMessage;
+ private final TextPaint mEmptyMessagePaint;
+ private final Point mLastMeasureSize = new Point();
+ private final int mEmptyMessagePadding;
+ private boolean mShowEmptyMessage;
+ private Layout mEmptyTextLayout;
+
+ private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
+ (inMultiWindowMode) -> {
+ if (!inMultiWindowMode && mOverviewStateEnabled) {
+ // TODO: Re-enable layout transitions for addition of the unpinned task
+ reloadIfNeeded();
+ }
+ };
+
+ public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
+ enableFreeScroll(true);
+ setClipToOutline(true);
+
+ mFastFlingVelocity = getResources()
+ .getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
+ mActivity = (T) BaseActivity.fromContext(context);
+ mQuickScrubController = new QuickScrubController(mActivity, this);
+ mModel = RecentsModel.getInstance(context);
+
+ mIsRtl = !Utilities.isRtl(getResources());
+ setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
+ mTaskTopMargin = getResources()
+ .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+
+ mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
+ mEmptyIcon.setCallback(this);
+ mEmptyMessage = context.getText(R.string.recents_empty_message);
+ mEmptyMessagePaint = new TextPaint();
+ mEmptyMessagePaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary));
+ mEmptyMessagePaint.setTextSize(getResources()
+ .getDimension(R.dimen.recents_empty_message_text_size));
+ mEmptyMessagePadding = getResources()
+ .getDimensionPixelSize(R.dimen.recents_empty_message_text_padding);
+ setWillNotDraw(false);
+ updateEmptyMessage();
+ setFocusable(false);
+ }
+
+ public boolean isRtl() {
+ return mIsRtl;
+ }
+
+ public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData) {
+ TaskView taskView = getTaskView(taskId);
+ if (taskView != null) {
+ taskView.onTaskDataLoaded(taskView.getTask(), thumbnailData);
+ }
+ return taskView;
+ }
+
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ updateTaskStackListenerState();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ updateTaskStackListenerState();
+ mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ updateTaskStackListenerState();
+ mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
+ }
+
+ @Override
+ public void onViewRemoved(View child) {
+ super.onViewRemoved(child);
+
+ // Clear the task data for the removed child if it was visible
+ Task task = ((TaskView) child).getTask();
+ if (mHasVisibleTaskData.get(task.key.id)) {
+ mHasVisibleTaskData.delete(task.key.id);
+ RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
+ loader.unloadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskInvisible(task);
+ }
+ onChildViewsChanged();
+ }
+
+ public boolean isTaskViewVisible(TaskView tv) {
+ // For now, just check if it's the active task or an adjacent task
+ return Math.abs(indexOfChild(tv) - getNextPage()) <= 1;
+ }
+
+ public TaskView getTaskView(int taskId) {
+ for (int i = 0; i < getChildCount(); i++) {
+ TaskView tv = (TaskView) getChildAt(i);
+ if (tv.getTask().key.id == taskId) {
+ return tv;
+ }
+ }
+ return null;
+ }
+
+ public void setOverviewStateEnabled(boolean enabled) {
+ mOverviewStateEnabled = enabled;
+ updateTaskStackListenerState();
+ }
+
+ public void setNextPageSwitchRunnable(Runnable r) {
+ mNextPageSwitchRunnable = r;
+ }
+
+ @Override
+ protected void onPageEndTransition() {
+ super.onPageEndTransition();
+ if (mNextPageSwitchRunnable != null) {
+ mNextPageSwitchRunnable.run();
+ mNextPageSwitchRunnable = null;
+ }
+ if (getNextPage() > 0) {
+ setSwipeDownShouldLaunchApp(true);
+ }
+ }
+
+ private int getScrollEnd() {
+ return mIsRtl ? 0 : mMaxScrollX;
+ }
+
+ private float calculateClearAllButtonAlpha() {
+ final int childCount = getChildCount();
+ if (mShowEmptyMessage || childCount == 0 || mPageScrolls == null
+ || childCount != mPageScrolls.length) {
+ return 0;
+ }
+
+ final int scrollEnd = getScrollEnd();
+ final int oldestChildScroll = getScrollForPage(childCount - 1);
+
+ final int clearAllButtonMotionRange = scrollEnd - oldestChildScroll;
+ if (clearAllButtonMotionRange == 0) return 0;
+
+ final float alphaUnbound = ((float) (getScrollX() - oldestChildScroll)) /
+ clearAllButtonMotionRange;
+ if (alphaUnbound > 1) return 0;
+
+ return Math.max(alphaUnbound, 0);
+ }
+
+ private void updateClearAllButtonAlpha() {
+ if (mClearAllButton != null) {
+ final float alpha = calculateClearAllButtonAlpha();
+ final boolean revealed = alpha == 1;
+ if (mIsClearAllButtonFullyRevealed != revealed) {
+ mIsClearAllButtonFullyRevealed = revealed;
+ mClearAllButton.setImportantForAccessibility(revealed ?
+ IMPORTANT_FOR_ACCESSIBILITY_YES :
+ IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+ mClearAllButton.setAlpha(alpha * mContentAlpha);
+ }
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ updateClearAllButtonAlpha();
+ }
+
+ @Override
+ protected void restoreScrollOnLayout() {
+ if (mIsClearAllButtonFullyRevealed) {
+ scrollAndForceFinish(getScrollEnd());
+ } else {
+ super.restoreScrollOnLayout();
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN && mTouchState == TOUCH_STATE_REST
+ && mScroller.isFinished() && mIsClearAllButtonFullyRevealed) {
+ mClearAllButton.getHitRect(mTempRect);
+ mTempRect.offset(-getLeft(), -getTop());
+ if (mTempRect.contains((int) ev.getX(), (int) ev.getY())) {
+ // If nothing is in motion, let the Clear All button process the event.
+ return false;
+ }
+ }
+
+ if (ev.getAction() == MotionEvent.ACTION_UP && mShowEmptyMessage) {
+ onAllTasksRemoved();
+ }
+ return super.onTouchEvent(ev);
+ }
+
+ private void applyLoadPlan(RecentsTaskLoadPlan loadPlan) {
+ if (mPendingAnimation != null) {
+ mPendingAnimation.addEndListener((onEndListener) -> applyLoadPlan(loadPlan));
+ return;
+ }
+ TaskStack stack = loadPlan != null ? loadPlan.getTaskStack() : null;
+ if (stack == null) {
+ removeAllViews();
+ onTaskStackUpdated();
+ return;
+ }
+
+ int oldChildCount = getChildCount();
+
+ // Ensure there are as many views as there are tasks in the stack (adding and trimming as
+ // necessary)
+ final LayoutInflater inflater = LayoutInflater.from(getContext());
+ final ArrayList tasks = new ArrayList<>(stack.getTasks());
+
+ final int requiredChildCount = tasks.size();
+ for (int i = getChildCount(); i < requiredChildCount; i++) {
+ final TaskView taskView = (TaskView) inflater.inflate(R.layout.task, this, false);
+ addView(taskView);
+ }
+ while (getChildCount() > requiredChildCount) {
+ final TaskView taskView = (TaskView) getChildAt(getChildCount() - 1);
+ removeView(taskView);
+ }
+
+ // Unload existing visible task data
+ unloadVisibleTaskData();
+
+ // Rebind and reset all task views
+ for (int i = requiredChildCount - 1; i >= 0; i--) {
+ final int pageIndex = requiredChildCount - i - 1;
+ final Task task = tasks.get(i);
+ final TaskView taskView = (TaskView) getChildAt(pageIndex);
+ taskView.bind(task);
+ }
+ resetTaskVisuals();
+
+ if (oldChildCount != getChildCount()) {
+ mQuickScrubController.snapToNextTaskIfAvailable();
+ }
+ onTaskStackUpdated();
+ }
+
+ protected void onTaskStackUpdated() { }
+
+ public void resetTaskVisuals() {
+ for (int i = getChildCount() - 1; i >= 0; i--) {
+ TaskView taskView = (TaskView) getChildAt(i);
+ if (!mIgnoreResetTaskViews.contains(taskView)) {
+ taskView.resetVisualProperties();
+ }
+ }
+ if (mRunningTaskTileHidden) {
+ setRunningTaskHidden(mRunningTaskTileHidden);
+ }
+ applyIconScale(false /* animate */);
+
+ updateCurveProperties();
+ // Update the set of visible task's data
+ loadVisibleTaskData();
+ }
+
+ private void updateTaskStackListenerState() {
+ boolean handleTaskStackChanges = mOverviewStateEnabled && isAttachedToWindow()
+ && getWindowVisibility() == VISIBLE;
+ if (handleTaskStackChanges != mHandleTaskStackChanges) {
+ mHandleTaskStackChanges = handleTaskStackChanges;
+ if (handleTaskStackChanges) {
+ reloadIfNeeded();
+ }
+ }
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ mInsets.set(insets);
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ getTaskSize(dp, mTempRect);
+
+ // Keep this logic in sync with ActivityControlHelper.getTranslationYForQuickScrub.
+ mTempRect.top -= mTaskTopMargin;
+ setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
+ dp.availableWidthPx + mInsets.left - mTempRect.right,
+ dp.availableHeightPx + mInsets.top - mTempRect.bottom);
+ }
+
+ protected abstract void getTaskSize(DeviceProfile dp, Rect outRect);
+
+ public void getTaskSize(Rect outRect) {
+ getTaskSize(mActivity.getDeviceProfile(), outRect);
+ }
+
+ @Override
+ protected boolean computeScrollHelper() {
+ boolean scrolling = super.computeScrollHelper();
+ boolean isFlingingFast = false;
+ updateCurveProperties();
+ if (scrolling || (mTouchState == TOUCH_STATE_SCROLLING)) {
+ if (scrolling) {
+ // Check if we are flinging quickly to disable high res thumbnail loading
+ isFlingingFast = mScroller.getCurrVelocity() > mFastFlingVelocity;
+ }
+
+ // After scrolling, update the visible task's data
+ loadVisibleTaskData();
+ }
+
+ // Update the high res thumbnail loader
+ RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
+ loader.getHighResThumbnailLoader().setFlingingFast(isFlingingFast);
+ return scrolling;
+ }
+
+ /**
+ * Scales and adjusts translation of adjacent pages as if on a curved carousel.
+ */
+ public void updateCurveProperties() {
+ if (getPageCount() == 0 || getPageAt(0).getMeasuredWidth() == 0) {
+ return;
+ }
+ final int halfPageWidth = getNormalChildWidth() / 2;
+ final int screenCenter = mInsets.left + getPaddingLeft() + getScrollX() + halfPageWidth;
+ final int halfScreenWidth = getMeasuredWidth() / 2;
+ final int pageSpacing = mPageSpacing;
+
+ final int pageCount = getPageCount();
+ for (int i = 0; i < pageCount; i++) {
+ View page = getPageAt(i);
+ float pageCenter = page.getLeft() + page.getTranslationX() + halfPageWidth;
+ float distanceFromScreenCenter = screenCenter - pageCenter;
+ float distanceToReachEdge = halfScreenWidth + halfPageWidth + pageSpacing;
+ mScrollState.linearInterpolation = Math.min(1,
+ Math.abs(distanceFromScreenCenter) / distanceToReachEdge);
+ ((PageCallbacks) page).onPageScroll(mScrollState);
+ }
+ }
+
+ /**
+ * Iterates through all thet asks, and loads the associated task data for newly visible tasks,
+ * and unloads the associated task data for tasks that are no longer visible.
+ */
+ public void loadVisibleTaskData() {
+ if (!mOverviewStateEnabled) {
+ // Skip loading visible task data if we've already left the overview state
+ return;
+ }
+
+ RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
+ int centerPageIndex = getPageNearestToCenterOfScreen();
+ int lower = Math.max(0, centerPageIndex - 2);
+ int upper = Math.min(centerPageIndex + 2, getChildCount() - 1);
+ int numChildren = getChildCount();
+
+ // Update the task data for the in/visible children
+ for (int i = 0; i < numChildren; i++) {
+ TaskView taskView = (TaskView) getChildAt(i);
+ Task task = taskView.getTask();
+ boolean visible = lower <= i && i <= upper;
+ if (visible) {
+ if (task == mTmpRunningTask) {
+ // Skip loading if this is the task that we are animating into
+ continue;
+ }
+ if (!mHasVisibleTaskData.get(task.key.id)) {
+ loader.loadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskVisible(task);
+ }
+ mHasVisibleTaskData.put(task.key.id, visible);
+ } else {
+ if (mHasVisibleTaskData.get(task.key.id)) {
+ loader.unloadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskInvisible(task);
+ }
+ mHasVisibleTaskData.delete(task.key.id);
+ }
+ }
+ }
+
+ /**
+ * Unloads any associated data from the currently visible tasks
+ */
+ private void unloadVisibleTaskData() {
+ RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
+ for (int i = 0; i < mHasVisibleTaskData.size(); i++) {
+ if (mHasVisibleTaskData.valueAt(i)) {
+ TaskView taskView = getTaskView(mHasVisibleTaskData.keyAt(i));
+ Task task = taskView.getTask();
+ loader.unloadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskInvisible(task);
+ }
+ }
+ mHasVisibleTaskData.clear();
+ }
+
+ protected abstract void onAllTasksRemoved();
+
+ public void reset() {
+ mRunningTaskId = -1;
+ mRunningTaskTileHidden = false;
+
+ unloadVisibleTaskData();
+ setCurrentPage(0);
+
+ OverviewCallbacks.get(getContext()).onResetOverview();
+ }
+
+ /**
+ * Reloads the view if anything in recents changed.
+ */
+ public void reloadIfNeeded() {
+ if (!mModel.isLoadPlanValid(mLoadPlanId)) {
+ mLoadPlanId = mModel.loadTasks(mRunningTaskId, this::applyLoadPlan);
+ }
+ }
+
+ /**
+ * Ensures that the first task in the view represents {@param task} and reloads the view
+ * if needed. This allows the swipe-up gesture to assume that the first tile always
+ * corresponds to the correct task.
+ * All subsequent calls to reload will keep the task as the first item until {@link #reset()}
+ * is called.
+ * Also scrolls the view to this task
+ */
+ public void showTask(int runningTaskId) {
+ if (getChildCount() == 0) {
+ // Add an empty view for now until the task plan is loaded and applied
+ final TaskView taskView = (TaskView) LayoutInflater.from(getContext())
+ .inflate(R.layout.task, this, false);
+ addView(taskView);
+
+ // The temporary running task is only used for the duration between the start of the
+ // gesture and the task list is loaded and applied
+ mTmpRunningTask = new Task(new Task.TaskKey(runningTaskId, 0, new Intent(), 0, 0), null,
+ null, "", "", 0, 0, false, true, false, false,
+ new ActivityManager.TaskDescription(), 0, new ComponentName("", ""), false);
+ taskView.bind(mTmpRunningTask);
+ }
+ setCurrentTask(runningTaskId);
+ }
+
+ /**
+ * Hides the tile associated with {@link #mRunningTaskId}
+ */
+ public void setRunningTaskHidden(boolean isHidden) {
+ mRunningTaskTileHidden = isHidden;
+ TaskView runningTask = getTaskView(mRunningTaskId);
+ if (runningTask != null) {
+ runningTask.setAlpha(isHidden ? 0 : mContentAlpha);
+ }
+ }
+
+ /**
+ * Similar to {@link #showTask(int)} but does not put any restrictions on the first tile.
+ */
+ public void setCurrentTask(int runningTaskId) {
+ boolean runningTaskTileHidden = mRunningTaskTileHidden;
+ boolean runningTaskIconScaledDown = mRunningTaskIconScaledDown;
+
+ setRunningTaskIconScaledDown(false, false);
+ setRunningTaskHidden(false);
+ mRunningTaskId = runningTaskId;
+ setRunningTaskIconScaledDown(runningTaskIconScaledDown, false);
+ setRunningTaskHidden(runningTaskTileHidden);
+
+ setCurrentPage(0);
+
+ // Load the tasks (if the loading is already
+ mLoadPlanId = mModel.loadTasks(runningTaskId, this::applyLoadPlan);
+ }
+
+ public void showNextTask() {
+ TaskView runningTaskView = getTaskView(mRunningTaskId);
+ if (runningTaskView == null) {
+ // Launch the first task
+ if (getChildCount() > 0) {
+ ((TaskView) getChildAt(0)).launchTask(true /* animate */);
+ }
+ } else {
+ // Get the next launch task
+ int runningTaskIndex = indexOfChild(runningTaskView);
+ int nextTaskIndex = Math.max(0, Math.min(getChildCount() - 1, runningTaskIndex + 1));
+ if (nextTaskIndex < getChildCount()) {
+ ((TaskView) getChildAt(nextTaskIndex)).launchTask(true /* animate */);
+ }
+ }
+ }
+
+ public QuickScrubController getQuickScrubController() {
+ return mQuickScrubController;
+ }
+
+ public void setRunningTaskIconScaledDown(boolean isScaledDown, boolean animate) {
+ if (mRunningTaskIconScaledDown == isScaledDown) {
+ return;
+ }
+ mRunningTaskIconScaledDown = isScaledDown;
+ applyIconScale(animate);
+ }
+
+ private void applyIconScale(boolean animate) {
+ float scale = mRunningTaskIconScaledDown ? 0 : 1;
+ TaskView firstTask = getTaskView(mRunningTaskId);
+ if (firstTask != null) {
+ if (animate) {
+ firstTask.animateIconToScaleAndDim(scale);
+ } else {
+ firstTask.setIconScaleAndDim(scale);
+ }
+ }
+ }
+
+ public void setSwipeDownShouldLaunchApp(boolean swipeDownShouldLaunchApp) {
+ mSwipeDownShouldLaunchApp = swipeDownShouldLaunchApp;
+ }
+
+ public boolean shouldSwipeDownLaunchApp() {
+ return mSwipeDownShouldLaunchApp;
+ }
+
+ public interface PageCallbacks {
+
+ /**
+ * Updates the page UI based on scroll params.
+ */
+ default void onPageScroll(ScrollState scrollState) {};
+ }
+
+ public static class ScrollState {
+
+ /**
+ * The progress from 0 to 1, where 0 is the center
+ * of the screen and 1 is the edge of the screen.
+ */
+ public float linearInterpolation;
+ }
+
+ public void addIgnoreResetTask(TaskView taskView) {
+ mIgnoreResetTaskViews.add(taskView);
+ }
+
+ public void removeIgnoreResetTask(TaskView taskView) {
+ mIgnoreResetTaskViews.remove(taskView);
+ }
+
+ private void addDismissedTaskAnimations(View taskView, AnimatorSet anim, long duration) {
+ addAnim(ObjectAnimator.ofFloat(taskView, ALPHA, 0), duration, ACCEL_2, anim);
+ addAnim(ObjectAnimator.ofFloat(taskView, TRANSLATION_Y, -taskView.getHeight()),
+ duration, LINEAR, anim);
+ }
+
+ private void removeTask(Task task, int index, PendingAnimation.OnEndListener onEndListener,
+ boolean shouldLog) {
+ if (task != null) {
+ ActivityManagerWrapper.getInstance().removeTask(task.key.id);
+ if (shouldLog) {
+ mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
+ onEndListener.logAction, Direction.UP, index,
+ TaskUtils.getComponentKeyForTask(task.key));
+ }
+ }
+ }
+
+ public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
+ boolean shouldRemoveTask, long duration) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && mPendingAnimation != null) {
+ throw new IllegalStateException("Another pending animation is still running");
+ }
+ AnimatorSet anim = new AnimatorSet();
+ PendingAnimation pendingAnimation = new PendingAnimation(anim);
+
+ int count = getChildCount();
+ if (count == 0) {
+ return pendingAnimation;
+ }
+
+ int[] oldScroll = new int[count];
+ getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC);
+
+ int[] newScroll = new int[count];
+ getPageScrolls(newScroll, false, (v) -> v.getVisibility() != GONE && v != taskView);
+
+ int scrollDiffPerPage = 0;
+ int leftmostPage = mIsRtl ? count -1 : 0;
+ int rightmostPage = mIsRtl ? 0 : count - 1;
+ if (count > 1) {
+ int secondRightmostPage = mIsRtl ? 1 : count - 2;
+ scrollDiffPerPage = oldScroll[rightmostPage] - oldScroll[secondRightmostPage];
+ }
+ int draggedIndex = indexOfChild(taskView);
+
+ boolean needsCurveUpdates = false;
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ if (child == taskView) {
+ if (animateTaskView) {
+ addDismissedTaskAnimations(taskView, anim, duration);
+ }
+ } else {
+ // If we just take newScroll - oldScroll, everything to the right of dragged task
+ // translates to the left. We need to offset this in some cases:
+ // - In RTL, add page offset to all pages, since we want pages to move to the right
+ // Additionally, add a page offset if:
+ // - Current page is rightmost page (leftmost for RTL)
+ // - Dragging an adjacent page on the left side (right side for RTL)
+ int offset = mIsRtl ? scrollDiffPerPage : 0;
+ if (mCurrentPage == draggedIndex) {
+ int lastPage = mIsRtl ? leftmostPage : rightmostPage;
+ if (mCurrentPage == lastPage) {
+ offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
+ }
+ } else {
+ // Dragging an adjacent page.
+ int negativeAdjacent = mCurrentPage - 1; // (Right in RTL, left in LTR)
+ if (draggedIndex == negativeAdjacent) {
+ offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
+ }
+ }
+ int scrollDiff = newScroll[i] - oldScroll[i] + offset;
+ if (scrollDiff != 0) {
+ addAnim(ObjectAnimator.ofFloat(child, TRANSLATION_X, scrollDiff),
+ duration, ACCEL, anim);
+ needsCurveUpdates = true;
+ }
+ }
+ }
+
+ if (needsCurveUpdates) {
+ ValueAnimator va = ValueAnimator.ofFloat(0, 1);
+ va.addUpdateListener((a) -> updateCurveProperties());
+ anim.play(va);
+ }
+
+ // Add a tiny bit of translation Z, so that it draws on top of other views
+ if (animateTaskView) {
+ taskView.setTranslationZ(0.1f);
+ }
+
+ mPendingAnimation = pendingAnimation;
+ mPendingAnimation.addEndListener((onEndListener) -> {
+ if (onEndListener.isSuccess) {
+ if (shouldRemoveTask) {
+ removeTask(taskView.getTask(), draggedIndex, onEndListener, true);
+ }
+ int pageToSnapTo = mCurrentPage;
+ if (draggedIndex < pageToSnapTo) {
+ pageToSnapTo -= 1;
+ }
+ removeView(taskView);
+ if (getChildCount() == 0) {
+ onAllTasksRemoved();
+ } else if (!mIsClearAllButtonFullyRevealed) {
+ snapToPageImmediately(pageToSnapTo);
+ }
+ }
+ resetTaskVisuals();
+ mPendingAnimation = null;
+ });
+ return pendingAnimation;
+ }
+
+ public PendingAnimation createAllTasksDismissAnimation(long duration) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && mPendingAnimation != null) {
+ throw new IllegalStateException("Another pending animation is still running");
+ }
+ AnimatorSet anim = new AnimatorSet();
+ PendingAnimation pendingAnimation = new PendingAnimation(anim);
+
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ addDismissedTaskAnimations(getChildAt(i), anim, duration);
+ }
+
+ mPendingAnimation = pendingAnimation;
+ mPendingAnimation.addEndListener((onEndListener) -> {
+ if (onEndListener.isSuccess) {
+ while (getChildCount() != 0) {
+ TaskView taskView = getPageAt(getChildCount() - 1);
+ removeTask(taskView.getTask(), -1, onEndListener, false);
+ removeView(taskView);
+ }
+ onAllTasksRemoved();
+ }
+ mPendingAnimation = null;
+ });
+ return pendingAnimation;
+ }
+
+ private static void addAnim(ObjectAnimator anim, long duration,
+ TimeInterpolator interpolator, AnimatorSet set) {
+ anim.setDuration(duration).setInterpolator(interpolator);
+ set.play(anim);
+ }
+
+ private boolean snapToPageRelative(int delta, boolean cycle) {
+ if (getPageCount() == 0) {
+ return false;
+ }
+ final int newPageUnbound = getNextPage() + delta;
+ if (!cycle && (newPageUnbound < 0 || newPageUnbound >= getChildCount())) {
+ return false;
+ }
+ snapToPage((newPageUnbound + getPageCount()) % getPageCount());
+ return true;
+ }
+
+ private void runDismissAnimation(PendingAnimation pendingAnim) {
+ AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(
+ pendingAnim.anim, DISMISS_TASK_DURATION);
+ controller.dispatchOnStart();
+ controller.setEndAction(() -> pendingAnim.finish(true, Touch.SWIPE));
+ controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
+ controller.start();
+ }
+
+ public void dismissTask(TaskView taskView, boolean animateTaskView, boolean removeTask) {
+ runDismissAnimation(createTaskDismissAnimation(taskView, animateTaskView, removeTask,
+ DISMISS_TASK_DURATION));
+ }
+
+ public void dismissAllTasks() {
+ runDismissAnimation(createAllTasksDismissAnimation(DISMISS_TASK_DURATION));
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_TAB:
+ return snapToPageRelative(event.isShiftPressed() ? -1 : 1,
+ event.isAltPressed() /* cycle */);
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ return snapToPageRelative(mIsRtl ? -1 : 1, false /* cycle */);
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ return snapToPageRelative(mIsRtl ? 1 : -1, false /* cycle */);
+ case KeyEvent.KEYCODE_DEL:
+ case KeyEvent.KEYCODE_FORWARD_DEL:
+ dismissTask((TaskView) getChildAt(getNextPage()), true /*animateTaskView*/,
+ true /*removeTask*/);
+ return true;
+ case KeyEvent.KEYCODE_NUMPAD_DOT:
+ if (event.isAltPressed()) {
+ // Numpad DEL pressed while holding Alt.
+ dismissTask((TaskView) getChildAt(getNextPage()), true /*animateTaskView*/,
+ true /*removeTask*/);
+ return true;
+ }
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean gainFocus, int direction,
+ @Nullable Rect previouslyFocusedRect) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ if (gainFocus && getChildCount() > 0) {
+ switch (direction) {
+ case FOCUS_FORWARD:
+ setCurrentPage(0);
+ break;
+ case FOCUS_BACKWARD:
+ case FOCUS_RIGHT:
+ case FOCUS_LEFT:
+ setCurrentPage(getChildCount() - 1);
+ break;
+ }
+ }
+ }
+
+ public float getContentAlpha() {
+ return mContentAlpha;
+ }
+
+ public void setContentAlpha(float alpha) {
+ alpha = Utilities.boundToRange(alpha, 0, 1);
+ mContentAlpha = alpha;
+ for (int i = getChildCount() - 1; i >= 0; i--) {
+ TaskView child = getPageAt(i);
+ if (!mRunningTaskTileHidden || child.getTask().key.id != mRunningTaskId) {
+ getChildAt(i).setAlpha(alpha);
+ }
+ }
+
+ int alphaInt = Math.round(alpha * 255);
+ mEmptyMessagePaint.setAlpha(alphaInt);
+ mEmptyIcon.setAlpha(alphaInt);
+ updateClearAllButtonAlpha();
+ }
+
+ private float[] getAdjacentScaleAndTranslation(TaskView currTask,
+ float currTaskToScale, float currTaskToTranslationY) {
+ float displacement = currTask.getWidth() * (currTaskToScale - currTask.getCurveScale());
+ sTempFloatArray[0] = currTaskToScale;
+ sTempFloatArray[1] = mIsRtl ? -displacement : displacement;
+ sTempFloatArray[2] = currTaskToTranslationY;
+ return sTempFloatArray;
+ }
+
+ @Override
+ public void onViewAdded(View child) {
+ super.onViewAdded(child);
+ child.setAlpha(mContentAlpha);
+ onChildViewsChanged();
+ }
+
+ @Override
+ public TaskView getPageAt(int index) {
+ return (TaskView) getChildAt(index);
+ }
+
+ public void updateEmptyMessage() {
+ boolean isEmpty = getChildCount() == 0;
+ boolean hasSizeChanged = mLastMeasureSize.x != getWidth()
+ || mLastMeasureSize.y != getHeight();
+ if (isEmpty == mShowEmptyMessage && !hasSizeChanged) {
+ return;
+ }
+ setContentDescription(isEmpty ? mEmptyMessage : "");
+ mShowEmptyMessage = isEmpty;
+ updateEmptyStateUi(hasSizeChanged);
+ invalidate();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ updateEmptyStateUi(changed);
+
+ // Set the pivot points to match the task preview center
+ setPivotY(((mInsets.top + getPaddingTop() + mTaskTopMargin)
+ + (getHeight() - mInsets.bottom - getPaddingBottom())) / 2);
+ setPivotX(((mInsets.left + getPaddingLeft())
+ + (getWidth() - mInsets.right - getPaddingRight())) / 2);
+ }
+
+ private void updateEmptyStateUi(boolean sizeChanged) {
+ boolean hasValidSize = getWidth() > 0 && getHeight() > 0;
+ if (sizeChanged && hasValidSize) {
+ mEmptyTextLayout = null;
+ mLastMeasureSize.set(getWidth(), getHeight());
+ }
+ updateClearAllButtonAlpha();
+
+ if (mShowEmptyMessage && hasValidSize && mEmptyTextLayout == null) {
+ int availableWidth = mLastMeasureSize.x - mEmptyMessagePadding - mEmptyMessagePadding;
+ mEmptyTextLayout = StaticLayout.Builder.obtain(mEmptyMessage, 0, mEmptyMessage.length(),
+ mEmptyMessagePaint, availableWidth)
+ .setAlignment(Layout.Alignment.ALIGN_CENTER)
+ .build();
+ int totalHeight = mEmptyTextLayout.getHeight()
+ + mEmptyMessagePadding + mEmptyIcon.getIntrinsicHeight();
+
+ int top = (mLastMeasureSize.y - totalHeight) / 2;
+ int left = (mLastMeasureSize.x - mEmptyIcon.getIntrinsicWidth()) / 2;
+ mEmptyIcon.setBounds(left, top, left + mEmptyIcon.getIntrinsicWidth(),
+ top + mEmptyIcon.getIntrinsicHeight());
+ }
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who) || (mShowEmptyMessage && who == mEmptyIcon);
+ }
+
+ protected void maybeDrawEmptyMessage(Canvas canvas) {
+ if (mShowEmptyMessage && mEmptyTextLayout != null) {
+ // Offset to center in the visible (non-padded) part of RecentsView
+ mTempRect.set(mInsets.left + getPaddingLeft(), mInsets.top + getPaddingTop(),
+ mInsets.right + getPaddingRight(), mInsets.bottom + getPaddingBottom());
+ canvas.save();
+ canvas.translate(getScrollX() + (mTempRect.left - mTempRect.right) / 2,
+ (mTempRect.top - mTempRect.bottom) / 2);
+ mEmptyIcon.draw(canvas);
+ canvas.translate(mEmptyMessagePadding,
+ mEmptyIcon.getBounds().bottom + mEmptyMessagePadding);
+ mEmptyTextLayout.draw(canvas);
+ canvas.restore();
+ }
+ }
+
+ /**
+ * Animate adjacent tasks off screen while scaling up.
+ *
+ * If launching one of the adjacent tasks, parallax the center task and other adjacent task
+ * to the right.
+ */
+ public AnimatorSet createAdjacentPageAnimForTaskLaunch(
+ TaskView tv, ClipAnimationHelper clipAnimationHelper) {
+ AnimatorSet anim = new AnimatorSet();
+
+ int taskIndex = indexOfChild(tv);
+ int centerTaskIndex = getCurrentPage();
+ boolean launchingCenterTask = taskIndex == centerTaskIndex;
+
+ float toScale = clipAnimationHelper.getSourceRect().width()
+ / clipAnimationHelper.getTargetRect().width();
+ float toTranslationY = clipAnimationHelper.getSourceRect().centerY()
+ - clipAnimationHelper.getTargetRect().centerY();
+ if (launchingCenterTask) {
+ TaskView centerTask = getPageAt(centerTaskIndex);
+ if (taskIndex - 1 >= 0) {
+ TaskView adjacentTask = getPageAt(taskIndex - 1);
+ float[] scaleAndTranslation = getAdjacentScaleAndTranslation(centerTask,
+ toScale, toTranslationY);
+ scaleAndTranslation[1] = -scaleAndTranslation[1];
+ anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
+ }
+ if (taskIndex + 1 < getPageCount()) {
+ TaskView adjacentTask = getPageAt(taskIndex + 1);
+ float[] scaleAndTranslation = getAdjacentScaleAndTranslation(centerTask,
+ toScale, toTranslationY);
+ anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
+ }
+ } else {
+ // We are launching an adjacent task, so parallax the center and other adjacent task.
+ float displacementX = tv.getWidth() * (toScale - tv.getCurveScale());
+ anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex), TRANSLATION_X,
+ mIsRtl ? -displacementX : displacementX));
+
+ int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - taskIndex);
+ if (otherAdjacentTaskIndex >= 0 && otherAdjacentTaskIndex < getPageCount()) {
+ anim.play(ObjectAnimator.ofPropertyValuesHolder(getPageAt(otherAdjacentTaskIndex),
+ new PropertyListBuilder()
+ .translationX(mIsRtl ? -displacementX : displacementX)
+ .scale(1)
+ .build()));
+ }
+ }
+ return anim;
+ }
+
+ private Animator createAnimForChild(TaskView child, float[] toScaleAndTranslation) {
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(ObjectAnimator.ofFloat(child, TaskView.ZOOM_SCALE, toScaleAndTranslation[0]));
+ anim.play(ObjectAnimator.ofPropertyValuesHolder(child,
+ new PropertyListBuilder()
+ .translationX(toScaleAndTranslation[1])
+ .translationY(toScaleAndTranslation[2])
+ .build()));
+ return anim;
+ }
+
+ public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && mPendingAnimation != null) {
+ throw new IllegalStateException("Another pending animation is still running");
+ }
+
+ int count = getChildCount();
+ if (count == 0) {
+ return new PendingAnimation(new AnimatorSet());
+ }
+
+ tv.setVisibility(INVISIBLE);
+ int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
+ TaskViewDrawable drawable = new TaskViewDrawable(tv, this);
+ getOverlay().add(drawable);
+
+ ObjectAnimator drawableAnim =
+ ObjectAnimator.ofFloat(drawable, TaskViewDrawable.PROGRESS, 1, 0);
+ drawableAnim.setInterpolator(LINEAR);
+ drawableAnim.addUpdateListener((animator) -> {
+ // Once we pass a certain threshold, update the sysui flags to match the target tasks'
+ // flags
+ mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW,
+ animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD
+ ? targetSysUiFlags
+ : 0);
+ });
+
+ AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv,
+ drawable.getClipAnimationHelper());
+ anim.play(drawableAnim);
+ anim.setDuration(duration);
+
+ Consumer onTaskLaunchFinish = (result) -> {
+ onTaskLaunched(result);
+ tv.setVisibility(VISIBLE);
+ getOverlay().remove(drawable);
+ };
+
+ mPendingAnimation = new PendingAnimation(anim);
+ mPendingAnimation.addEndListener((onEndListener) -> {
+ if (onEndListener.isSuccess) {
+ Consumer onLaunchResult = (result) -> {
+ onTaskLaunchFinish.accept(result);
+ if (!result) {
+ tv.notifyTaskLaunchFailed(TAG);
+ }
+ };
+ tv.launchTask(false, onLaunchResult, getHandler());
+ Task task = tv.getTask();
+ if (task != null) {
+ mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
+ onEndListener.logAction, Direction.DOWN, indexOfChild(tv),
+ TaskUtils.getComponentKeyForTask(task.key));
+ }
+ } else {
+ onTaskLaunchFinish.accept(false);
+ }
+ mPendingAnimation = null;
+ });
+ return mPendingAnimation;
+ }
+
+ public abstract boolean shouldUseMultiWindowTaskSizeStrategy();
+
+ protected void onTaskLaunched(boolean success) {
+ resetTaskVisuals();
+ }
+
+ @Override
+ protected void notifyPageSwitchListener(int prevPage) {
+ super.notifyPageSwitchListener(prevPage);
+ loadVisibleTaskData();
+ }
+
+ @Override
+ protected String getCurrentPageDescription() {
+ return "";
+ }
+
+ private int additionalScrollForClearAllButton() {
+ return (int) getResources().getDimension(
+ R.dimen.clear_all_container_width) - getPaddingEnd();
+ }
+
+ @Override
+ protected int computeMaxScrollX() {
+ if (getChildCount() == 0) {
+ return super.computeMaxScrollX();
+ }
+
+ // Allow a clear_all_container_width-sized gap after the last task.
+ return super.computeMaxScrollX() + (mIsRtl ? 0 : additionalScrollForClearAllButton());
+ }
+
+ @Override
+ protected int offsetForPageScrolls() {
+ return mIsRtl ? additionalScrollForClearAllButton() : 0;
+ }
+
+ public void setClearAllButton(View clearAllButton) {
+ mClearAllButton = clearAllButton;
+ updateClearAllButtonAlpha();
+ }
+
+ private void onChildViewsChanged() {
+ final int childCount = getChildCount();
+ mClearAllButton.setVisibility(childCount == 0 ? INVISIBLE : VISIBLE);
+ setFocusable(childCount != 0);
+ }
+
+ public void revealClearAllButton() {
+ setCurrentPage(getChildCount() - 1); // Loads tasks info if needed.
+ scrollTo(mIsRtl ? 0 : computeMaxScrollX(), 0);
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (getChildCount() > 0) {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+ if (!mIsClearAllButtonFullyRevealed && getCurrentPage() == getPageCount() - 1) {
+ revealClearAllButton();
+ return true;
+ }
+ }
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+ if (mIsClearAllButtonFullyRevealed) {
+ setCurrentPage(getChildCount() - 1);
+ return true;
+ }
+ }
+ break;
+ }
+ }
+ return super.performAccessibilityAction(action, arguments);
+ }
+
+ @Override
+ public void addChildrenForAccessibility(ArrayList outChildren) {
+ outChildren.add(mClearAllButton);
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ outChildren.add(getChildAt(i));
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+
+ if (getChildCount() > 0) {
+ info.addAction(mIsClearAllButtonFullyRevealed ?
+ AccessibilityNodeInfo.ACTION_SCROLL_FORWARD :
+ AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.setScrollable(true);
+ }
+
+ final AccessibilityNodeInfo.CollectionInfo
+ collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
+ 1, getChildCount(), false,
+ AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_NONE);
+ info.setCollectionInfo(collectionInfo);
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+
+ event.setScrollable(getPageCount() > 0);
+
+ if (!mIsClearAllButtonFullyRevealed
+ && event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ final int childCount = getChildCount();
+ final int[] visibleTasks = getVisibleChildrenRange();
+ event.setFromIndex(childCount - visibleTasks[1] - 1);
+ event.setToIndex(childCount - visibleTasks[0] - 1);
+ event.setItemCount(childCount);
+ }
+ }
+
+ @Override
+ public CharSequence getAccessibilityClassName() {
+ // To hear position-in-list related feedback from Talkback.
+ return ListView.class.getName();
+ }
+
+ @Override
+ protected boolean isPageOrderFlipped() {
+ return true;
+ }
+
+ public boolean performTaskAccessibilityActionExtra(int action) {
+ return false;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
new file mode 100644
index 0000000000..c6cd52769e
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.views;
+
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.R;
+
+import java.util.ArrayList;
+
+public class RecentsViewContainer extends InsettableFrameLayout {
+ public static final FloatProperty CONTENT_ALPHA =
+ new FloatProperty("contentAlpha") {
+ @Override
+ public void setValue(RecentsViewContainer view, float v) {
+ view.setContentAlpha(v);
+ }
+
+ @Override
+ public Float get(RecentsViewContainer view) {
+ return view.mRecentsView.getContentAlpha();
+ }
+ };
+
+ private final Rect mTempRect = new Rect();
+
+ private RecentsView mRecentsView;
+ private ClearAllButton mClearAllButton;
+
+ public RecentsViewContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mClearAllButton = findViewById(R.id.clear_all_button);
+ mClearAllButton.setOnClickListener((v) -> {
+ mRecentsView.mActivity.getUserEventDispatcher()
+ .logActionOnControl(TAP, CLEAR_ALL_BUTTON);
+ mRecentsView.dismissAllTasks();
+ });
+
+ mRecentsView = findViewById(R.id.overview_panel);
+ mClearAllButton.forceHasOverlappingRendering(false);
+
+ mRecentsView.setClearAllButton(mClearAllButton);
+ mClearAllButton.setRecentsView(mRecentsView);
+
+ if (mRecentsView.isRtl()) {
+ mClearAllButton.setNextFocusRightId(mRecentsView.getId());
+ mRecentsView.setNextFocusLeftId(mClearAllButton.getId());
+ } else {
+ mClearAllButton.setNextFocusLeftId(mRecentsView.getId());
+ mRecentsView.setNextFocusRightId(mClearAllButton.getId());
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ mRecentsView.getTaskSize(mTempRect);
+
+ mClearAllButton.setTranslationX(
+ (mRecentsView.isRtl() ? 1 : -1) *
+ (getResources().getDimension(R.dimen.clear_all_container_width)
+ - mClearAllButton.getMeasuredWidth()) / 2);
+ mClearAllButton.setTranslationY(
+ mTempRect.top + (mTempRect.height() - mClearAllButton.getMeasuredHeight()) / 2
+ - mClearAllButton.getTop());
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ super.onTouchEvent(ev);
+ // Do not let touch escape to siblings below this view. This prevents scrolling of the
+ // workspace while in Recents.
+ return true;
+ }
+
+ public void setContentAlpha(float alpha) {
+ if (alpha == mRecentsView.getContentAlpha()) {
+ return;
+ }
+ mRecentsView.setContentAlpha(alpha);
+ setVisibility(alpha > 0 ? VISIBLE : GONE);
+ }
+
+ @Override
+ public void addFocusables(ArrayList views, int direction, int focusableMode) {
+ if (mRecentsView.getChildCount() > 0) {
+ // Carousel is first in tab order.
+ views.add(mRecentsView);
+ views.add(mClearAllButton);
+ }
+ }
+
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
+ return mRecentsView.requestFocus(direction, previouslyFocusedRect) ||
+ super.requestFocus(direction, previouslyFocusedRect);
+ }
+
+ @Override
+ public void addChildrenForAccessibility(ArrayList outChildren) {
+ outChildren.add(mRecentsView);
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
new file mode 100644
index 0000000000..c780b62340
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import static android.support.v4.graphics.ColorUtils.compositeColors;
+import static android.support.v4.graphics.ColorUtils.setAlphaComponent;
+
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Path.Op;
+import android.util.AttributeSet;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.uioverrides.OverviewState;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ScrimView;
+
+/**
+ * Scrim used for all-apps and shelf in Overview
+ * In transposed layout, it behaves as a simple color scrim.
+ * In portrait layout, it draws a rounded rect such that
+ * From normal state to overview state, the shelf just fades in and does not move
+ * From overview state to all-apps state the shelf moves up and fades in to cover the screen
+ */
+public class ShelfScrimView extends ScrimView {
+
+ // In transposed layout, we simply draw a flat color.
+ private boolean mDrawingFlatColor;
+
+ // For shelf mode
+ private final int mEndAlpha;
+ private final int mThresholdAlpha;
+ private final float mRadius;
+ private final float mMaxScrimAlpha;
+ private final Paint mPaint;
+
+ // Max vertical progress after which the scrim stops moving.
+ private float mMoveThreshold;
+ // Minimum visible size of the scrim.
+ private int mMinSize;
+
+ private float mScrimMoveFactor = 0;
+ private int mShelfColor;
+ private int mRemainingScreenColor;
+
+ private final Path mTempPath = new Path();
+ private final Path mRemainingScreenPath = new Path();
+ private boolean mRemainingScreenPathValid = false;
+
+ public ShelfScrimView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);
+
+ mEndAlpha = Color.alpha(mEndScrim);
+ mThresholdAlpha = Themes.getAttrInteger(context, R.attr.allAppsInterimScrimAlpha);
+ mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
+ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ // Just assume the easiest UI for now, until we have the proper layout information.
+ mDrawingFlatColor = true;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ mRemainingScreenPathValid = false;
+ }
+
+ @Override
+ public void reInitUi() {
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ mDrawingFlatColor = dp.isVerticalBarLayout();
+
+ if (!mDrawingFlatColor) {
+ float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
+ mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
+ mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
+ mRemainingScreenPathValid = false;
+ updateColors();
+ }
+ updateDragHandleAlpha();
+ invalidate();
+ }
+
+ @Override
+ public void updateColors() {
+ super.updateColors();
+ if (mDrawingFlatColor) {
+ return;
+ }
+
+ if (mProgress >= mMoveThreshold) {
+ mScrimMoveFactor = 1;
+
+ if (mProgress >= 1) {
+ mShelfColor = 0;
+ } else {
+ int alpha = Math.round(mThresholdAlpha * ACCEL_2.getInterpolation(
+ (1 - mProgress) / (1 - mMoveThreshold)));
+ mShelfColor = setAlphaComponent(mEndScrim, alpha);
+ }
+
+ mRemainingScreenColor = 0;
+ } else if (mProgress <= 0) {
+ mScrimMoveFactor = 0;
+ mShelfColor = mCurrentFlatColor;
+ mRemainingScreenColor = 0;
+
+ } else {
+ mScrimMoveFactor = mProgress / mMoveThreshold;
+ mRemainingScreenColor = setAlphaComponent(mScrimColor,
+ Math.round((1 - mScrimMoveFactor) * mMaxScrimAlpha * 255));
+
+ // Merge the remainingScreenColor and shelfColor in one to avoid overdraw.
+ int alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * mScrimMoveFactor);
+ mShelfColor = compositeColors(setAlphaComponent(mEndScrim, alpha),
+ mRemainingScreenColor);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ float translate = drawBackground(canvas);
+
+ if (mDragHandle != null) {
+ canvas.translate(0, -translate);
+ mDragHandle.draw(canvas);
+ canvas.translate(0, translate);
+ }
+ }
+
+ private float drawBackground(Canvas canvas) {
+ if (mDrawingFlatColor) {
+ if (mCurrentFlatColor != 0) {
+ canvas.drawColor(mCurrentFlatColor);
+ }
+ return 0;
+ }
+
+ if (mShelfColor == 0) {
+ return 0;
+ } else if (mScrimMoveFactor <= 0) {
+ canvas.drawColor(mShelfColor);
+ return getHeight();
+ }
+
+ float minTop = getHeight() - mMinSize;
+ float top = minTop * mScrimMoveFactor - mDragHandleSize;
+
+ // Draw the scrim over the remaining screen if needed.
+ if (mRemainingScreenColor != 0) {
+ if (!mRemainingScreenPathValid) {
+ mTempPath.reset();
+ // Using a arbitrary '+10' in the bottom to avoid any left-overs at the
+ // corners due to rounding issues.
+ mTempPath.addRoundRect(0, minTop, getWidth(), getHeight() + mRadius + 10,
+ mRadius, mRadius, Direction.CW);
+
+ mRemainingScreenPath.reset();
+ mRemainingScreenPath.addRect(0, 0, getWidth(), getHeight(), Direction.CW);
+ mRemainingScreenPath.op(mTempPath, Op.DIFFERENCE);
+ }
+
+ float offset = minTop - top;
+ canvas.translate(0, -offset);
+ mPaint.setColor(mRemainingScreenColor);
+ canvas.drawPath(mRemainingScreenPath, mPaint);
+ canvas.translate(0, offset);
+ }
+
+ mPaint.setColor(mShelfColor);
+ canvas.drawRoundRect(0, top, getWidth(), getHeight() + mRadius,
+ mRadius, mRadius, mPaint);
+ return minTop - mDragHandleSize - top;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
new file mode 100644
index 0000000000..dd90c8867d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.views;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.Outline;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.TextView;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.shortcuts.DeepShortcutView;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.TaskSystemShortcut;
+import com.android.quickstep.TaskUtils;
+
+/**
+ * Contains options for a recent task when long-pressing its icon.
+ */
+public class TaskMenuView extends AbstractFloatingView {
+
+ private static final Rect sTempRect = new Rect();
+
+ /** Note that these will be shown in order from top to bottom, if available for the task. */
+ public static final TaskSystemShortcut[] MENU_OPTIONS = new TaskSystemShortcut[] {
+ new TaskSystemShortcut.AppInfo(),
+ new TaskSystemShortcut.SplitScreen(),
+ new TaskSystemShortcut.Pin(),
+ new TaskSystemShortcut.Install(),
+ };
+
+ private static final long OPEN_CLOSE_DURATION = 220;
+
+ private BaseDraggingActivity mActivity;
+ private TextView mTaskIconAndName;
+ private AnimatorSet mOpenCloseAnimator;
+ private TaskView mTaskView;
+
+ public TaskMenuView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TaskMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ mActivity = BaseDraggingActivity.fromContext(context);
+ setClipToOutline(true);
+ setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ float r = getResources().getDimensionPixelSize(R.dimen.task_menu_background_radius);
+ outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), r);
+ }
+ });
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mTaskIconAndName = findViewById(R.id.task_icon_and_name);
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ BaseDragLayer dl = mActivity.getDragLayer();
+ if (!dl.isEventOverView(this, ev)) {
+ // TODO: log this once we have a new container type for it?
+ close(true);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected void handleClose(boolean animate) {
+ if (animate) {
+ animateClose();
+ } else {
+ closeComplete();
+ }
+ }
+
+ @Override
+ public void logActionCommand(int command) {
+ // TODO
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_TASK_MENU) != 0;
+ }
+
+ public static boolean showForTask(TaskView taskView) {
+ BaseDraggingActivity activity = BaseDraggingActivity.fromContext(taskView.getContext());
+ final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
+ R.layout.task_menu, activity.getDragLayer(), false);
+ return taskMenuView.populateAndShowForTask(taskView);
+ }
+
+ private boolean populateAndShowForTask(TaskView taskView) {
+ if (isAttachedToWindow()) {
+ return false;
+ }
+ mActivity.getDragLayer().addView(this);
+ mTaskView = taskView;
+ addMenuOptions(mTaskView);
+ orientAroundTaskView(mTaskView);
+ post(this::animateOpen);
+ return true;
+ }
+
+ private void addMenuOptions(TaskView taskView) {
+ Drawable icon = taskView.getTask().icon.getConstantState().newDrawable();
+ int iconSize = getResources().getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
+ icon.setBounds(0, 0, iconSize, iconSize);
+ mTaskIconAndName.setCompoundDrawables(null, icon, null, null);
+ mTaskIconAndName.setText(TaskUtils.getTitle(getContext(), taskView.getTask()));
+ mTaskIconAndName.setOnClickListener(v -> close(true));
+
+ for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
+ OnClickListener onClickListener = menuOption.getOnClickListener(mActivity, taskView);
+ if (onClickListener != null) {
+ addMenuOption(menuOption, onClickListener);
+ }
+ }
+ }
+
+ private void addMenuOption(TaskSystemShortcut menuOption, OnClickListener onClickListener) {
+ DeepShortcutView menuOptionView = (DeepShortcutView) mActivity.getLayoutInflater().inflate(
+ R.layout.system_shortcut, this, false);
+ menuOptionView.getIconView().setBackgroundResource(menuOption.iconResId);
+ menuOptionView.getBubbleText().setText(menuOption.labelResId);
+ menuOptionView.setOnClickListener(onClickListener);
+ addView(menuOptionView);
+ }
+
+ private void orientAroundTaskView(TaskView taskView) {
+ measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
+ Rect insets = mActivity.getDragLayer().getInsets();
+ int x = sTempRect.left + (sTempRect.width() - getMeasuredWidth()) / 2 - insets.left;
+ setX(Utilities.isRtl(getResources()) ? -x : x);
+ setY(sTempRect.top - mTaskIconAndName.getPaddingTop() - insets.top);
+ }
+
+ private void animateOpen() {
+ animateOpenOrClosed(false);
+ mIsOpen = true;
+ }
+
+ private void animateClose() {
+ animateOpenOrClosed(true);
+ }
+
+ private void animateOpenOrClosed(boolean closing) {
+ if (mOpenCloseAnimator != null && mOpenCloseAnimator.isRunning()) {
+ return;
+ }
+ mOpenCloseAnimator = LauncherAnimUtils.createAnimatorSet();
+ mOpenCloseAnimator.play(createOpenCloseOutlineProvider()
+ .createRevealAnimator(this, closing));
+ mOpenCloseAnimator.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ setVisibility(VISIBLE);
+ }
+
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ if (closing) {
+ closeComplete();
+ }
+ }
+ });
+ mOpenCloseAnimator.play(ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
+ mOpenCloseAnimator.setDuration(OPEN_CLOSE_DURATION);
+ mOpenCloseAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
+ mOpenCloseAnimator.start();
+ }
+
+ private void closeComplete() {
+ mIsOpen = false;
+ mActivity.getDragLayer().removeView(this);
+ }
+
+ private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() {
+ int iconSize = getResources().getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
+ float fromRadius = iconSize / 2;
+ float toRadius = getResources().getDimensionPixelSize(
+ R.dimen.task_menu_background_radius);
+ Point iconCenter = new Point(getWidth() / 2, mTaskIconAndName.getPaddingTop() + iconSize / 2);
+ Rect fromRect = new Rect(iconCenter.x, iconCenter.y, iconCenter.x, iconCenter.y);
+ Rect toRect = new Rect(0, 0, getWidth(), getHeight());
+ return new RoundedRectRevealOutlineProvider(fromRadius, toRadius, fromRect, toRect) {
+ @Override
+ public boolean shouldRemoveElevationDuringAnimation() {
+ return true;
+ }
+ };
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
new file mode 100644
index 0000000000..d9dfd1815d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -0,0 +1,317 @@
+/*
+ * 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.quickstep.views;
+
+import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LightingColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.support.v4.graphics.ColorUtils;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.util.Property;
+import android.view.View;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.SystemUiController;
+import com.android.launcher3.util.Themes;
+import com.android.quickstep.TaskOverlayFactory;
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+/**
+ * A task in the Recents view.
+ */
+public class TaskThumbnailView extends View {
+
+ private static final LightingColorFilter[] sDimFilterCache = new LightingColorFilter[256];
+ private static final LightingColorFilter[] sHighlightFilterCache = new LightingColorFilter[256];
+
+ public static final Property DIM_ALPHA_MULTIPLIER =
+ new FloatProperty("dimAlphaMultiplier") {
+ @Override
+ public void setValue(TaskThumbnailView thumbnail, float dimAlphaMultiplier) {
+ thumbnail.setDimAlphaMultipler(dimAlphaMultiplier);
+ }
+
+ @Override
+ public Float get(TaskThumbnailView thumbnailView) {
+ return thumbnailView.mDimAlphaMultiplier;
+ }
+ };
+
+ private final float mCornerRadius;
+
+ private final BaseActivity mActivity;
+ private final TaskOverlay mOverlay;
+ private final boolean mIsDarkTextTheme;
+ private final Paint mPaint = new Paint();
+ private final Paint mBackgroundPaint = new Paint();
+
+ private final Matrix mMatrix = new Matrix();
+
+ private float mClipBottom = -1;
+
+ private Task mTask;
+ private ThumbnailData mThumbnailData;
+ protected BitmapShader mBitmapShader;
+
+ private float mDimAlpha = 1f;
+ private float mDimAlphaMultiplier = 1f;
+
+ public TaskThumbnailView(Context context) {
+ this(context, null);
+ }
+
+ public TaskThumbnailView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mCornerRadius = getResources().getDimension(R.dimen.task_corner_radius);
+ mOverlay = TaskOverlayFactory.get(context).createOverlay(this);
+ mPaint.setFilterBitmap(true);
+ mBackgroundPaint.setColor(Color.WHITE);
+ mActivity = BaseActivity.fromContext(context);
+ mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
+ }
+
+ public void bind() {
+ mOverlay.reset();
+ }
+
+ /**
+ * Updates this thumbnail.
+ */
+ public void setThumbnail(Task task, ThumbnailData thumbnailData) {
+ mTask = task;
+ int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
+ mPaint.setColor(color);
+ mBackgroundPaint.setColor(color);
+
+ if (thumbnailData != null && thumbnailData.thumbnail != null) {
+ Bitmap bm = thumbnailData.thumbnail;
+ bm.prepareToDraw();
+ mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ mPaint.setShader(mBitmapShader);
+ mThumbnailData = thumbnailData;
+ updateThumbnailMatrix();
+ } else {
+ mBitmapShader = null;
+ mThumbnailData = null;
+ mPaint.setShader(null);
+ mOverlay.reset();
+ }
+ updateThumbnailPaintFilter();
+ }
+
+ public void setDimAlphaMultipler(float dimAlphaMultipler) {
+ mDimAlphaMultiplier = dimAlphaMultipler;
+ setDimAlpha(mDimAlpha);
+ }
+
+ /**
+ * Sets the alpha of the dim layer on top of this view.
+ *
+ * If dimAlpha is 0, no dimming is applied; if dimAlpha is 1, the thumbnail will be black.
+ */
+ public void setDimAlpha(float dimAlpha) {
+ mDimAlpha = dimAlpha;
+ updateThumbnailPaintFilter();
+ }
+
+ public Rect getInsets() {
+ if (mThumbnailData != null) {
+ return mThumbnailData.insets;
+ }
+ return new Rect();
+ }
+
+ public int getSysUiStatusNavFlags() {
+ if (mThumbnailData != null) {
+ int flags = 0;
+ flags |= (mThumbnailData.systemUiVisibility & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0
+ ? SystemUiController.FLAG_LIGHT_STATUS
+ : SystemUiController.FLAG_DARK_STATUS;
+ flags |= (mThumbnailData.systemUiVisibility & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0
+ ? SystemUiController.FLAG_LIGHT_NAV
+ : SystemUiController.FLAG_DARK_NAV;
+ return flags;
+ }
+ return 0;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius);
+ }
+
+ public float getCornerRadius() {
+ return mCornerRadius;
+ }
+
+ public void drawOnCanvas(Canvas canvas, float x, float y, float width, float height,
+ float cornerRadius) {
+ // Draw the background in all cases, except when the thumbnail data is opaque
+ final boolean drawBackgroundOnly = mTask == null || mTask.isLocked || mBitmapShader == null
+ || mThumbnailData == null;
+ if (drawBackgroundOnly || mClipBottom > 0 || mThumbnailData.isTranslucent) {
+ canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint);
+ if (drawBackgroundOnly) {
+ return;
+ }
+ }
+
+ if (mClipBottom > 0) {
+ canvas.save();
+ canvas.clipRect(x, y, width, mClipBottom);
+ canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
+ canvas.restore();
+ } else {
+ canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
+ }
+ }
+
+ private void updateThumbnailPaintFilter() {
+ int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
+ if (mBitmapShader != null) {
+ LightingColorFilter filter = getDimmingColorFilter(mul, mIsDarkTextTheme);
+ mPaint.setColorFilter(filter);
+ mBackgroundPaint.setColorFilter(filter);
+ } else {
+ mPaint.setColorFilter(null);
+ mPaint.setColor(Color.argb(255, mul, mul, mul));
+ }
+ invalidate();
+ }
+
+ private void updateThumbnailMatrix() {
+ boolean rotate = false;
+ mClipBottom = -1;
+ if (mBitmapShader != null && mThumbnailData != null) {
+ float scale = mThumbnailData.scale;
+ Rect thumbnailInsets = mThumbnailData.insets;
+ final float thumbnailWidth = mThumbnailData.thumbnail.getWidth() -
+ (thumbnailInsets.left + thumbnailInsets.right) * scale;
+ final float thumbnailHeight = mThumbnailData.thumbnail.getHeight() -
+ (thumbnailInsets.top + thumbnailInsets.bottom) * scale;
+
+ final float thumbnailScale;
+ final DeviceProfile profile = mActivity.getDeviceProfile();
+
+ if (getMeasuredWidth() == 0) {
+ // If we haven't measured , skip the thumbnail drawing and only draw the background
+ // color
+ thumbnailScale = 0f;
+ } else {
+ final Configuration configuration =
+ getContext().getResources().getConfiguration();
+ // Rotate the screenshot if not in multi-window mode
+ rotate = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
+ configuration.orientation != mThumbnailData.orientation &&
+ !mActivity.isInMultiWindowModeCompat() &&
+ mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
+ // Scale the screenshot to always fit the width of the card.
+ thumbnailScale = rotate
+ ? getMeasuredWidth() / thumbnailHeight
+ : getMeasuredWidth() / thumbnailWidth;
+ }
+
+ if (rotate) {
+ int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
+ mMatrix.setRotate(90 * rotationDir);
+ int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
+ int newTopInset = rotationDir == 1 ? thumbnailInsets.left : thumbnailInsets.right;
+ mMatrix.postTranslate(-newLeftInset * scale, -newTopInset * scale);
+ if (rotationDir == -1) {
+ // Crop the right/bottom side of the screenshot rather than left/top
+ float excessHeight = thumbnailWidth * thumbnailScale - getMeasuredHeight();
+ mMatrix.postTranslate(0, -excessHeight);
+ }
+ // Move the screenshot to the thumbnail window (rotation moved it out).
+ if (rotationDir == 1) {
+ mMatrix.postTranslate(mThumbnailData.thumbnail.getHeight(), 0);
+ } else {
+ mMatrix.postTranslate(0, mThumbnailData.thumbnail.getWidth());
+ }
+ } else {
+ mMatrix.setTranslate(-mThumbnailData.insets.left * scale,
+ -mThumbnailData.insets.top * scale);
+ }
+ mMatrix.postScale(thumbnailScale, thumbnailScale);
+ mBitmapShader.setLocalMatrix(mMatrix);
+
+ float bitmapHeight = Math.max((rotate ? thumbnailWidth : thumbnailHeight)
+ * thumbnailScale, 0);
+ if (Math.round(bitmapHeight) < getMeasuredHeight()) {
+ mClipBottom = bitmapHeight;
+ }
+ mPaint.setShader(mBitmapShader);
+ }
+
+ if (rotate) {
+ // The overlay doesn't really work when the screenshot is rotated, so don't add it.
+ mOverlay.reset();
+ } else {
+ mOverlay.setTaskInfo(mTask, mThumbnailData, mMatrix);
+ }
+ invalidate();
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ updateThumbnailMatrix();
+ }
+
+ private static LightingColorFilter getDimmingColorFilter(int intensity, boolean shouldLighten) {
+ intensity = Utilities.boundToRange(intensity, 0, 255);
+ if (intensity == 255) {
+ return null;
+ }
+ if (shouldLighten) {
+ if (sHighlightFilterCache[intensity] == null) {
+ int colorAdd = 255 - intensity;
+ sHighlightFilterCache[intensity] = new LightingColorFilter(
+ Color.argb(255, intensity, intensity, intensity),
+ Color.argb(255, colorAdd, colorAdd, colorAdd));
+ }
+ return sHighlightFilterCache[intensity];
+ } else {
+ if (sDimFilterCache[intensity] == null) {
+ sDimFilterCache[intensity] = new LightingColorFilter(
+ Color.argb(255, intensity, intensity, intensity), 0);
+ }
+ return sDimFilterCache[intensity];
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
new file mode 100644
index 0000000000..b5f31b8e2e
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -0,0 +1,367 @@
+/*
+ * 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.quickstep.views;
+
+import static android.widget.Toast.LENGTH_SHORT;
+
+import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA_MULTIPLIER;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Outline;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.util.Log;
+import android.util.Property;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.FrameLayout;
+import android.widget.Toast;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.R;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.quickstep.TaskSystemShortcut;
+import com.android.quickstep.TaskUtils;
+import com.android.quickstep.views.RecentsView.PageCallbacks;
+import com.android.quickstep.views.RecentsView.ScrollState;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskCallbacks;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+
+import java.util.function.Consumer;
+
+/**
+ * A task in the Recents view.
+ */
+public class TaskView extends FrameLayout implements TaskCallbacks, PageCallbacks {
+
+ private static final String TAG = TaskView.class.getSimpleName();
+
+ /** A curve of x from 0 to 1, where 0 is the center of the screen and 1 is the edge. */
+ private static final TimeInterpolator CURVE_INTERPOLATOR
+ = x -> (float) -Math.cos(x * Math.PI) / 2f + .5f;
+
+ /**
+ * The alpha of a black scrim on a page in the carousel as it leaves the screen.
+ * In the resting position of the carousel, the adjacent pages have about half this scrim.
+ */
+ private static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
+
+ /**
+ * How much to scale down pages near the edge of the screen.
+ */
+ private static final float EDGE_SCALE_DOWN_FACTOR = 0.03f;
+
+ public static final long SCALE_ICON_DURATION = 120;
+ private static final long DIM_ANIM_DURATION = 700;
+
+ public static final Property ZOOM_SCALE =
+ new FloatProperty("zoomScale") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setZoomScale(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mZoomScale;
+ }
+ };
+
+ private Task mTask;
+ private TaskThumbnailView mSnapshotView;
+ private IconView mIconView;
+ private float mCurveScale;
+ private float mZoomScale;
+ private Animator mDimAlphaAnim;
+
+ public TaskView(Context context) {
+ this(context, null);
+ }
+
+ public TaskView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setOnClickListener((view) -> {
+ if (getTask() == null) {
+ return;
+ }
+ launchTask(true /* animate */);
+ BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
+ Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
+ TaskUtils.getComponentKeyForTask(getTask().key));
+ });
+ setOutlineProvider(new TaskOutlineProvider(getResources()));
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mSnapshotView = findViewById(R.id.snapshot);
+ mIconView = findViewById(R.id.icon);
+ }
+
+ /**
+ * Updates this task view to the given {@param task}.
+ */
+ public void bind(Task task) {
+ if (mTask != null) {
+ mTask.removeCallback(this);
+ }
+ mTask = task;
+ mSnapshotView.bind();
+ task.addCallback(this);
+ setContentDescription(task.titleDescription);
+ }
+
+ public Task getTask() {
+ return mTask;
+ }
+
+ public TaskThumbnailView getThumbnail() {
+ return mSnapshotView;
+ }
+
+ public IconView getIconView() {
+ return mIconView;
+ }
+
+ public void launchTask(boolean animate) {
+ launchTask(animate, (result) -> {
+ if (!result) {
+ notifyTaskLaunchFailed(TAG);
+ }
+ }, getHandler());
+ }
+
+ public void launchTask(boolean animate, Consumer resultCallback,
+ Handler resultCallbackHandler) {
+ if (mTask != null) {
+ final ActivityOptions opts;
+ if (animate) {
+ opts = BaseDraggingActivity.fromContext(getContext())
+ .getActivityLaunchOptions(this);
+ } else {
+ opts = ActivityOptions.makeCustomAnimation(getContext(), 0, 0);
+ }
+ ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(mTask.key,
+ opts, resultCallback, resultCallbackHandler);
+ }
+ }
+
+ @Override
+ public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData) {
+ mSnapshotView.setThumbnail(task, thumbnailData);
+ mIconView.setDrawable(task.icon);
+ mIconView.setOnClickListener(icon -> TaskMenuView.showForTask(this));
+ mIconView.setOnLongClickListener(icon -> {
+ requestDisallowInterceptTouchEvent(true);
+ return TaskMenuView.showForTask(this);
+ });
+ }
+
+ @Override
+ public void onTaskDataUnloaded() {
+ mSnapshotView.setThumbnail(null, null);
+ mIconView.setDrawable(null);
+ mIconView.setOnLongClickListener(null);
+ }
+
+ @Override
+ public void onTaskWindowingModeChanged() {
+ // Do nothing
+ }
+
+ public void animateIconToScaleAndDim(float scale) {
+ mIconView.animate().scaleX(scale).scaleY(scale).setDuration(SCALE_ICON_DURATION).start();
+ mDimAlphaAnim = ObjectAnimator.ofFloat(mSnapshotView, DIM_ALPHA_MULTIPLIER, 1 - scale,
+ scale);
+ mDimAlphaAnim.setDuration(DIM_ANIM_DURATION);
+ mDimAlphaAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDimAlphaAnim = null;
+ }
+ });
+ mDimAlphaAnim.start();
+ }
+
+ protected void setIconScaleAndDim(float iconScale) {
+ mIconView.animate().cancel();
+ mIconView.setScaleX(iconScale);
+ mIconView.setScaleY(iconScale);
+ if (mDimAlphaAnim != null) {
+ mDimAlphaAnim.cancel();
+ }
+ mSnapshotView.setDimAlphaMultipler(iconScale);
+ }
+
+ public void resetVisualProperties() {
+ setZoomScale(1);
+ setTranslationX(0f);
+ setTranslationY(0f);
+ setTranslationZ(0);
+ setAlpha(1f);
+ setIconScaleAndDim(1);
+ }
+
+ @Override
+ public void onPageScroll(ScrollState scrollState) {
+ float curveInterpolation =
+ CURVE_INTERPOLATOR.getInterpolation(scrollState.linearInterpolation);
+
+ mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA);
+ setCurveScale(getCurveScaleForCurveInterpolation(curveInterpolation));
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ setPivotX((right - left) * 0.5f);
+ setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f);
+ }
+
+ public static float getCurveScaleForInterpolation(float linearInterpolation) {
+ float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation);
+ return getCurveScaleForCurveInterpolation(curveInterpolation);
+ }
+
+ private static float getCurveScaleForCurveInterpolation(float curveInterpolation) {
+ return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
+ }
+
+ private void setCurveScale(float curveScale) {
+ mCurveScale = curveScale;
+ onScaleChanged();
+ }
+
+ public float getCurveScale() {
+ return mCurveScale;
+ }
+
+ public void setZoomScale(float adjacentScale) {
+ mZoomScale = adjacentScale;
+ onScaleChanged();
+ }
+
+ private void onScaleChanged() {
+ float scale = mCurveScale * mZoomScale;
+ setScaleX(scale);
+ setScaleY(scale);
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ // TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
+ return false;
+ }
+
+ private static final class TaskOutlineProvider extends ViewOutlineProvider {
+
+ private final int mMarginTop;
+ private final float mRadius;
+
+ TaskOutlineProvider(Resources res) {
+ mMarginTop = res.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+ mRadius = res.getDimension(R.dimen.task_corner_radius);
+ }
+
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(0, mMarginTop, view.getWidth(),
+ view.getHeight(), mRadius);
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+
+ info.addAction(
+ new AccessibilityNodeInfo.AccessibilityAction(R.string.accessibility_close_task,
+ getContext().getText(R.string.accessibility_close_task)));
+
+ final Context context = getContext();
+ final BaseDraggingActivity activity = BaseDraggingActivity.fromContext(context);
+ for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) {
+ OnClickListener onClickListener = menuOption.getOnClickListener(activity, this);
+ if (onClickListener != null) {
+ info.addAction(new AccessibilityNodeInfo.AccessibilityAction(menuOption.labelResId,
+ context.getText(menuOption.labelResId)));
+ }
+ }
+
+ final RecentsView recentsView = getRecentsView();
+ final AccessibilityNodeInfo.CollectionItemInfo itemInfo =
+ AccessibilityNodeInfo.CollectionItemInfo.obtain(
+ 0, 1, recentsView.getChildCount() - recentsView.indexOfChild(this) - 1, 1,
+ false);
+ info.setCollectionItemInfo(itemInfo);
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (action == R.string.accessibility_close_task) {
+ getRecentsView().dismissTask(this, true /*animateTaskView*/,
+ true /*removeTask*/);
+ return true;
+ }
+
+ for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) {
+ if (action == menuOption.labelResId) {
+ OnClickListener onClickListener = menuOption.getOnClickListener(
+ BaseDraggingActivity.fromContext(getContext()), this);
+ if (onClickListener != null) {
+ onClickListener.onClick(this);
+ }
+ return true;
+ }
+ }
+
+ if (getRecentsView().performTaskAccessibilityActionExtra(action)) return true;
+
+ return super.performAccessibilityAction(action, arguments);
+ }
+
+ private RecentsView getRecentsView() {
+ return (RecentsView) getParent();
+ }
+
+ public void notifyTaskLaunchFailed(String tag) {
+ String msg = "Failed to launch task";
+ if (mTask != null) {
+ msg += " (task=" + mTask.key.baseIntent + " userId=" + mTask.key.userId + ")";
+ }
+ Log.w(tag, msg);
+ Toast.makeText(getContext(), R.string.activity_not_available, LENGTH_SHORT).show();
+ }
+}
diff --git a/res/animator-v23/discovery_bounce.xml b/res/animator-v23/discovery_bounce.xml
index 8d0e8fdfb5..f5548537b1 100644
--- a/res/animator-v23/discovery_bounce.xml
+++ b/res/animator-v23/discovery_bounce.xml
@@ -26,14 +26,14 @@
android:fraction="0"
android:value="1f" />
+ android:value="0.9738f" />
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable-hdpi/work_tab_user_education.png b/res/drawable-hdpi/work_tab_user_education.png
new file mode 100644
index 0000000000..1879dfb2b7
Binary files /dev/null and b/res/drawable-hdpi/work_tab_user_education.png differ
diff --git a/res/drawable-mdpi/work_tab_user_education.png b/res/drawable-mdpi/work_tab_user_education.png
new file mode 100644
index 0000000000..65c7e638dd
Binary files /dev/null and b/res/drawable-mdpi/work_tab_user_education.png differ
diff --git a/res/drawable-v24/ic_info_shadow.xml b/res/drawable-v24/ic_setup_shadow.xml
similarity index 94%
rename from res/drawable-v24/ic_info_shadow.xml
rename to res/drawable-v24/ic_setup_shadow.xml
index 1fe2c46b4b..10aeee6e02 100644
--- a/res/drawable-v24/ic_info_shadow.xml
+++ b/res/drawable-v24/ic_setup_shadow.xml
@@ -15,5 +15,5 @@
-->
diff --git a/res/drawable-xhdpi/work_tab_user_education.png b/res/drawable-xhdpi/work_tab_user_education.png
new file mode 100644
index 0000000000..59df7a8647
Binary files /dev/null and b/res/drawable-xhdpi/work_tab_user_education.png differ
diff --git a/res/drawable-xxhdpi/work_tab_user_education.png b/res/drawable-xxhdpi/work_tab_user_education.png
new file mode 100644
index 0000000000..3c6aa208ea
Binary files /dev/null and b/res/drawable-xxhdpi/work_tab_user_education.png differ
diff --git a/res/drawable/all_apps_search_divider.xml b/res/drawable/bg_all_apps_searchbox.xml
similarity index 78%
rename from res/drawable/all_apps_search_divider.xml
rename to res/drawable/bg_all_apps_searchbox.xml
index 99905e4233..c3249279af 100644
--- a/res/drawable/all_apps_search_divider.xml
+++ b/res/drawable/bg_all_apps_searchbox.xml
@@ -1,5 +1,5 @@
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/res/drawable/bg_deferred_app_widget.xml b/res/drawable/bg_deferred_app_widget.xml
new file mode 100644
index 0000000000..07bae480b2
--- /dev/null
+++ b/res/drawable/bg_deferred_app_widget.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
diff --git a/res/drawable/bg_notification_content.xml b/res/drawable/bg_notification_content.xml
new file mode 100644
index 0000000000..cf129eba82
--- /dev/null
+++ b/res/drawable/bg_notification_content.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+ -
+
+
+
+
+
diff --git a/res/drawable/drag_handle_indicator.xml b/res/drawable/drag_handle_indicator.xml
new file mode 100644
index 0000000000..b01b84ab81
--- /dev/null
+++ b/res/drawable/drag_handle_indicator.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_close.xml b/res/drawable/ic_close.xml
new file mode 100644
index 0000000000..8b2f55fb32
--- /dev/null
+++ b/res/drawable/ic_close.xml
@@ -0,0 +1,23 @@
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_star_rating.xml b/res/drawable/ic_corp.xml
similarity index 60%
rename from res/drawable/ic_star_rating.xml
rename to res/drawable/ic_corp.xml
index 4e34fa33e8..48f50076c9 100644
--- a/res/drawable/ic_star_rating.xml
+++ b/res/drawable/ic_corp.xml
@@ -14,14 +14,11 @@
limitations under the License.
-->
-
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:pathData="M20,6h-4V4c0,-1.11 -0.89,-2 -2,-2h-4C8.89,2 8,2.89 8,4v2H4C2.89,6 2.01,6.89 2.01,8L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V8C22,6.89 21.11,6 20,6zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2s2,0.9 2,2S13.1,15 12,15zM14,6h-4V4h4V6z"
+ android:fillColor="?android:attr/textColorHint"/>
\ No newline at end of file
diff --git a/res/drawable/ic_install_no_shadow.xml b/res/drawable/ic_install_no_shadow.xml
new file mode 100644
index 0000000000..ffce22aac1
--- /dev/null
+++ b/res/drawable/ic_install_no_shadow.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/res/drawable/ic_setting.xml b/res/drawable/ic_setting.xml
index 1bab18990e..a83aab3204 100644
--- a/res/drawable/ic_setting.xml
+++ b/res/drawable/ic_setting.xml
@@ -14,17 +14,30 @@ Copyright (C) 2016 The Android Open Source Project
limitations under the License.
-->
+ android:width="@dimen/options_menu_icon_size"
+ android:height="@dimen/options_menu_icon_size"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/textColorPrimary" >
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M13.85,22.25h-3.7c-0.74,0-1.36-0.54-1.45-1.27l-0.27-1.89c-0.27-0.14-0.53-0.29-0.79-0.46l-1.8,0.72
+ c-0.7,0.26-1.47-0.03-1.81-0.65L2.2,15.53c-0.35-0.66-0.2-1.44,0.36-1.88l1.53-1.19c-0.01-0.15-0.02-0.3-0.02-0.46
+ c0-0.15,0.01-0.31,0.02-0.46l-1.52-1.19C1.98,9.9,1.83,9.09,2.2,8.47l1.85-3.19c0.34-0.62,1.11-0.9,1.79-0.63l1.81,0.73
+ c0.26-0.17,0.52-0.32,0.78-0.46l0.27-1.91c0.09-0.7,0.71-1.25,1.44-1.25h3.7c0.74,0,1.36,0.54,1.45,1.27l0.27,1.89
+ c0.27,0.14,0.53,0.29,0.79,0.46l1.8-0.72c0.71-0.26,1.48,0.03,1.82,0.65l1.84,3.18c0.36,0.66,0.2,1.44-0.36,1.88l-1.52,1.19
+ c0.01,0.15,0.02,0.3,0.02,0.46s-0.01,0.31-0.02,0.46l1.52,1.19c0.56,0.45,0.72,1.23,0.37,1.86l-1.86,3.22
+ c-0.34,0.62-1.11,0.9-1.8,0.63l-1.8-0.72c-0.26,0.17-0.52,0.32-0.78,0.46l-0.27,1.91C15.21,21.71,14.59,22.25,13.85,22.25z
+ M13.32,20.72c0,0.01,0,0.01,0,0.02L13.32,20.72z M10.68,20.7l0,0.02C10.69,20.72,10.69,20.71,10.68,20.7z M10.62,20.25h2.76
+ l0.37-2.55l0.53-0.22c0.44-0.18,0.88-0.44,1.34-0.78l0.45-0.34l2.38,0.96l1.38-2.4l-2.03-1.58l0.07-0.56
+ c0.03-0.26,0.06-0.51,0.06-0.78c0-0.27-0.03-0.53-0.06-0.78l-0.07-0.56l2.03-1.58l-1.39-2.4l-2.39,0.96l-0.45-0.35
+ c-0.42-0.32-0.87-0.58-1.33-0.77L13.75,6.3l-0.37-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7,8.84,6.95,8.38,7.3L7.93,7.63
+ L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47,6.06,11.74,6.06,12c0,0.26,0.02,0.53,0.06,0.78l0.07,0.56l-2.03,1.58
+ l1.38,2.4l2.39-0.96l0.45,0.35c0.43,0.33,0.86,0.58,1.33,0.77l0.53,0.22L10.62,20.25z M18.22,17.72c0,0.01-0.01,0.02-0.01,0.03
+ L18.22,17.72z M5.77,17.71l0.01,0.02C5.78,17.72,5.77,17.71,5.77,17.71z M3.93,9.47L3.93,9.47C3.93,9.47,3.93,9.47,3.93,9.47z
+ M18.22,6.27c0,0.01,0.01,0.02,0.01,0.02L18.22,6.27z M5.79,6.25L5.78,6.27C5.78,6.27,5.79,6.26,5.79,6.25z M13.31,3.28
+ c0,0.01,0,0.01,0,0.02L13.31,3.28z M10.69,3.26l0,0.02C10.69,3.27,10.69,3.27,10.69,3.26z"/>
+
diff --git a/res/drawable/ic_uninstall_no_shadow.xml b/res/drawable/ic_uninstall_no_shadow.xml
index 2a86e1042d..37632d1a4b 100644
--- a/res/drawable/ic_uninstall_no_shadow.xml
+++ b/res/drawable/ic_uninstall_no_shadow.xml
@@ -21,6 +21,11 @@
android:tint="?android:attr/textColorPrimary" >
+ android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V6h1V4H15z M17,19H7V6h10V19z" />
+
+
diff --git a/res/drawable/ic_wallpaper.xml b/res/drawable/ic_wallpaper.xml
index 9e9222f645..7fd93403c5 100644
--- a/res/drawable/ic_wallpaper.xml
+++ b/res/drawable/ic_wallpaper.xml
@@ -14,16 +14,13 @@ Copyright (C) 2016 The Android Open Source Project
limitations under the License.
-->
+ android:width="@dimen/options_menu_icon_size"
+ android:height="@dimen/options_menu_icon_size"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:pathData="M9,12.71l2.14,2.58l3-3.87L18,16.57H6L9,12.71z M5,5h6V3H5C3.9,3,3,3.9,3,5v6h2V5z M19,19h-6v2h6c1.1,0,2-0.9,2-2v-6h-2V19z
+ M5,19v-6H3v6c0,1.1,0.9,2,2,2h6v-2H5z M19,5v6h2V5c0-1.1-0.9-2-2-2h-6v2H19z M16,9c0.55,0,1-0.45,1-1s-0.45-1-1-1
+ c-0.55,0-1,0.45-1,1S15.45,9,16,9z"/>
diff --git a/res/drawable/ic_widget.xml b/res/drawable/ic_widget.xml
index de2980f09c..3ebbb68bb9 100644
--- a/res/drawable/ic_widget.xml
+++ b/res/drawable/ic_widget.xml
@@ -14,13 +14,12 @@ Copyright (C) 2016 The Android Open Source Project
limitations under the License.
-->
+ android:width="@dimen/options_menu_icon_size"
+ android:height="@dimen/options_menu_icon_size"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:fillColor="?android:attr/textColorPrimary"
+ android:pathData="M16.66,4.52l2.83,2.83l-2.83,2.83l-2.83-2.83L16.66,4.52 M9,5v4H5V5H9 M19,15v4h-4v-4H19 M9,15v4H5v-4H9 M16.66,1.69
+ L11,7.34L16.66,13l5.66-5.66L16.66,1.69L16.66,1.69z M11,3H3v8h8V7.34V3L11,3z M21,13h-4.34H13v8h8V13L21,13z M11,13H3v8h8V13L11,13z"/>
diff --git a/res/drawable/round_rect_primary.xml b/res/drawable/round_rect_primary.xml
index 2c47e06536..16310f8bdc 100644
--- a/res/drawable/round_rect_primary.xml
+++ b/res/drawable/round_rect_primary.xml
@@ -17,5 +17,5 @@
-
+
diff --git a/res/drawable/tooltip_frame.xml b/res/drawable/tooltip_frame.xml
new file mode 100644
index 0000000000..03190518fa
--- /dev/null
+++ b/res/drawable/tooltip_frame.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/top_round_rect_primary.xml b/res/drawable/top_round_rect_primary.xml
new file mode 100644
index 0000000000..1caaa026f0
--- /dev/null
+++ b/res/drawable/top_round_rect_primary.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/res/layout-land/all_apps_fast_scroller.xml b/res/layout-land/all_apps_fast_scroller.xml
deleted file mode 100644
index 6a68f84e98..0000000000
--- a/res/layout-land/all_apps_fast_scroller.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
deleted file mode 100644
index ac440fc01e..0000000000
--- a/res/layout-land/launcher.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout-sw720dp/all_apps_fast_scroller.xml b/res/layout-sw720dp/all_apps_fast_scroller.xml
deleted file mode 100644
index 12c15cca9a..0000000000
--- a/res/layout-sw720dp/all_apps_fast_scroller.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
deleted file mode 100644
index 03e42bc1d0..0000000000
--- a/res/layout-sw720dp/launcher.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 39df2b193c..02d793e1c0 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -18,60 +18,21 @@
will bake the left/right padding into that view's background itself. -->
+ android:clipChildren="true"
+ android:clipToPadding="false"
+ android:focusable="false"
+ android:saveEnabled="false" >
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/res/layout/all_apps_discovery_item.xml b/res/layout/all_apps_discovery_item.xml
deleted file mode 100644
index 728283fc11..0000000000
--- a/res/layout/all_apps_discovery_item.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/all_apps_discovery_loading_divider.xml b/res/layout/all_apps_discovery_loading_divider.xml
deleted file mode 100644
index 005847c541..0000000000
--- a/res/layout/all_apps_discovery_loading_divider.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/all_apps_fast_scroller.xml b/res/layout/all_apps_fast_scroller.xml
index 12c15cca9a..5537bc60a5 100644
--- a/res/layout/all_apps_fast_scroller.xml
+++ b/res/layout/all_apps_fast_scroller.xml
@@ -21,7 +21,7 @@
android:id="@+id/fast_scroller_popup"
style="@style/FastScrollerPopup"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/apps_list_view"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
diff --git a/res/layout/all_apps_floating_header.xml b/res/layout/all_apps_floating_header.xml
new file mode 100644
index 0000000000..c4240f80db
--- /dev/null
+++ b/res/layout/all_apps_floating_header.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/all_apps_rv_layout.xml b/res/layout/all_apps_rv_layout.xml
new file mode 100644
index 0000000000..c353b361cf
--- /dev/null
+++ b/res/layout/all_apps_rv_layout.xml
@@ -0,0 +1,25 @@
+
+
+
diff --git a/res/layout/all_apps_tabs.xml b/res/layout/all_apps_tabs.xml
new file mode 100644
index 0000000000..2accd2d21f
--- /dev/null
+++ b/res/layout/all_apps_tabs.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/app_widget_resize_frame.xml b/res/layout/app_widget_resize_frame.xml
index 874fecccf3..12561b634d 100644
--- a/res/layout/app_widget_resize_frame.xml
+++ b/res/layout/app_widget_resize_frame.xml
@@ -21,42 +21,47 @@
android:background="@drawable/widget_resize_shadow"
android:foreground="@drawable/widget_resize_frame"
android:foregroundTint="?attr/workspaceTextColor"
- android:padding="0dp" >
+ android:padding="0dp">
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/drop_target_bar.xml b/res/layout/drop_target_bar.xml
new file mode 100644
index 0000000000..2f21c605a5
--- /dev/null
+++ b/res/layout/drop_target_bar.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/drop_target_bar_horz.xml b/res/layout/drop_target_bar_horz.xml
deleted file mode 100644
index ed18192c5b..0000000000
--- a/res/layout/drop_target_bar_horz.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/drop_target_bar_vert.xml b/res/layout/drop_target_bar_vert.xml
deleted file mode 100644
index 2394d0d138..0000000000
--- a/res/layout/drop_target_bar_vert.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/drop_target_tool_tip.xml b/res/layout/drop_target_tool_tip.xml
new file mode 100644
index 0000000000..a3efec4e31
--- /dev/null
+++ b/res/layout/drop_target_tool_tip.xml
@@ -0,0 +1,31 @@
+
+
+
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index 582a83fbe8..00f0b5ff8a 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -17,10 +17,12 @@
android:theme="@style/HomeScreenElementTheme"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto">
+
+ launcher:containerType="hotseat"
+ android:importantForAccessibility="no" />
diff --git a/res/layout-port/launcher.xml b/res/layout/launcher.xml
similarity index 65%
rename from res/layout-port/launcher.xml
rename to res/layout/launcher.xml
index c41a6e380d..da17b2b315 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout/launcher.xml
@@ -1,5 +1,4 @@
-
-
-
-
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:importantForAccessibility="no">
-
+ android:theme="@style/HomeScreenElementTheme"
+ launcher:pageIndicator="@+id/page_indicator" />
-
-
-
-
-
-
-
+ we go into AllApps -->
+
+ layout="@layout/drop_target_bar" />
-
+
-
+
+
+
diff --git a/res/layout/longpress_options_menu.xml b/res/layout/longpress_options_menu.xml
new file mode 100644
index 0000000000..20bb5b81be
--- /dev/null
+++ b/res/layout/longpress_options_menu.xml
@@ -0,0 +1,26 @@
+
+
+
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
deleted file mode 100644
index 1eebb434ba..0000000000
--- a/res/layout/notification.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml
new file mode 100644
index 0000000000..d01be019eb
--- /dev/null
+++ b/res/layout/notification_content.xml
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/notification_footer.xml b/res/layout/notification_footer.xml
deleted file mode 100644
index 86280e0b6d..0000000000
--- a/res/layout/notification_footer.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/gradient_bg.xml b/res/layout/notification_gutter.xml
similarity index 75%
rename from res/layout/gradient_bg.xml
rename to res/layout/notification_gutter.xml
index db448d7818..10e7f7d68a 100644
--- a/res/layout/gradient_bg.xml
+++ b/res/layout/notification_gutter.xml
@@ -13,12 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
\ No newline at end of file
+ android:layout_height="4dp"
+ android:layout_marginTop="4dp"
+ android:background="@drawable/bg_notification_content" />
\ No newline at end of file
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
deleted file mode 100644
index f94face1b1..0000000000
--- a/res/layout/notification_main.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index d1ac56c505..bdd5d23476 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -14,63 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ android:layout_width="0dp"
+ android:layout_height="0dp" />
\ No newline at end of file
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
deleted file mode 100644
index 92f52d672c..0000000000
--- a/res/layout/page_indicator.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml
index 67db4a5617..c73740771d 100644
--- a/res/layout/popup_container.xml
+++ b/res/layout/popup_container.xml
@@ -19,11 +19,8 @@
android:id="@+id/deep_shortcuts_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingTop="4dp"
- android:paddingBottom="4dp"
+ android:background="?attr/popupColorPrimary"
android:clipToPadding="false"
android:clipChildren="false"
android:elevation="@dimen/deep_shortcuts_elevation"
- android:orientation="vertical">
-
-
\ No newline at end of file
+ android:orientation="vertical" />
\ No newline at end of file
diff --git a/res/layout/scrim_view.xml b/res/layout/scrim_view.xml
new file mode 100644
index 0000000000..a604d569de
--- /dev/null
+++ b/res/layout/scrim_view.xml
@@ -0,0 +1,20 @@
+
+
+
\ No newline at end of file
diff --git a/res/layout/search_container_all_apps.xml b/res/layout/search_container_all_apps.xml
index fc07002cb5..fd9cb60fc7 100644
--- a/res/layout/search_container_all_apps.xml
+++ b/res/layout/search_container_all_apps.xml
@@ -17,53 +17,22 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/search_container_all_apps"
android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_search_bar_height"
- android:layout_gravity="center|top"
- android:layout_marginBottom="-8dp"
- android:gravity="center|bottom"
- android:paddingLeft="@dimen/dynamic_grid_edge_margin"
- android:paddingRight="@dimen/dynamic_grid_edge_margin"
- android:saveEnabled="false" >
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ android:layout_height="@dimen/all_apps_search_bar_field_height"
+ android:layout_centerHorizontal="true"
+ android:layout_gravity="top|center_horizontal"
+ android:background="@drawable/bg_all_apps_searchbox"
+ android:elevation="1dp"
+ android:focusableInTouchMode="true"
+ android:gravity="center"
+ android:hint="@string/all_apps_search_bar_hint"
+ android:imeOptions="actionSearch|flagNoExtractUi"
+ android:inputType="text|textNoSuggestions|textCapWords"
+ android:maxLines="1"
+ android:padding="8dp"
+ android:saveEnabled="false"
+ android:scrollHorizontally="true"
+ android:singleLine="true"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textColorHint="@drawable/all_apps_search_hint"
+ android:textSize="16sp"
+ android:translationY="24dp" />
\ No newline at end of file
diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml
index c59cb53319..b8b5b8c1c7 100644
--- a/res/layout/system_shortcut_icon_only.xml
+++ b/res/layout/system_shortcut_icon_only.xml
@@ -20,5 +20,6 @@
android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:tint="?android:attr/textColorHint"
+ android:tintMode="src_in"
android:padding="@dimen/system_shortcut_header_icon_padding"
android:theme="@style/PopupItem" />
diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml
index 34d63e71fe..4daf469589 100644
--- a/res/layout/system_shortcut_icons.xml
+++ b/res/layout/system_shortcut_icons.xml
@@ -22,6 +22,4 @@
android:orientation="horizontal"
android:gravity="end|center_vertical"
android:background="?attr/popupColorSecondary"
- android:elevation="1dp"
- android:outlineProvider="none" />
-
+ android:clipToPadding="true" />
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
deleted file mode 100644
index afa19b8970..0000000000
--- a/res/layout/user_folder.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index e8c6961f43..6bf90481ad 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="28dp"
- android:background="?android:attr/colorPrimary"
+ android:background="@drawable/top_round_rect_primary"
android:elevation="@dimen/deep_shortcuts_elevation"
android:layout_gravity="bottom"
android:theme="?attr/widgetsTheme">
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_full_sheet.xml
similarity index 50%
rename from res/layout/widgets_view.xml
rename to res/layout/widgets_full_sheet.xml
index 4f3c7c8df0..f507a88f1a 100644
--- a/res/layout/widgets_view.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -1,5 +1,5 @@
-
-
-
+ android:orientation="vertical"
+ android:theme="?attr/widgetsTheme" >
-
-
-
+ android:background="?android:attr/colorPrimary"
+ android:elevation="4dp">
+ android:layout_height="match_parent"
+ android:clipToPadding="false" />
-
-
-
-
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/res/layout/widgets_list_row_view.xml b/res/layout/widgets_list_row_view.xml
index 4cd03ce059..eec57a5df3 100644
--- a/res/layout/widgets_list_row_view.xml
+++ b/res/layout/widgets_list_row_view.xml
@@ -31,7 +31,6 @@
android:layout_height="@dimen/widget_section_height"
android:background="?android:attr/colorPrimary"
android:drawablePadding="@dimen/widget_section_horizontal_padding"
- android:ellipsize="end"
android:focusable="true"
android:gravity="start|center_vertical"
android:paddingBottom="@dimen/widget_section_vertical_padding"
@@ -42,7 +41,6 @@
android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp"
android:textAlignment="viewStart"
- launcher:deferShadowGeneration="true"
launcher:iconDisplay="widget_section"
launcher:iconSizeOverride="@dimen/widget_section_icon_size"
launcher:layoutHorizontal="true" />
diff --git a/res/layout/work_tab_bottom_user_education_view.xml b/res/layout/work_tab_bottom_user_education_view.xml
new file mode 100644
index 0000000000..ba6a939429
--- /dev/null
+++ b/res/layout/work_tab_bottom_user_education_view.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/work_tab_footer.xml b/res/layout/work_tab_footer.xml
new file mode 100644
index 0000000000..379e9d0b44
--- /dev/null
+++ b/res/layout/work_tab_footer.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/zzz_weight_watcher.xml b/res/layout/zzz_weight_watcher.xml
deleted file mode 100644
index 07fd39e91f..0000000000
--- a/res/layout/zzz_weight_watcher.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index d71b4c78b3..35539e3608 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -40,13 +40,18 @@
"Kon geen programme kry wat by \"%1$s\" pas nie"
"Soek meer programme"
"Kennisgewings"
+ "Raak en hou om \'n kortpad op te tel."
+ "Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge."
"Niks meer spasie op die tuisskerm nie."
"Geen plek meer in die Gunstelinge-laai nie"
"Programmelys"
+ "Lys persoonlike programme"
+ "Lys werkprogramme"
"Tuis"
"Verwyder"
"Deïnstalleer"
"Programinligting"
+ "Installeer"
"installeer kortpaaie"
"Laat \'n program toe om kortpaaie by te voeg sonder gebruikerinmenging."
"lees Tuis-instellings en -kortpaaie"
@@ -59,6 +64,10 @@
"Dit is \'n stelselprogram en kan nie gedeïnstalleer word nie."
"Naamlose vouer"
"Het %1$s gedeaktiveer"
+
+ - %1$s het %2$d kennisgewings
+ - %1$s het %2$d kennisgewing
+
"Bladsy %1$d van %2$d"
"Tuisskerm %1$d van %2$d"
"Nuwe tuisskermbladsy"
@@ -70,21 +79,21 @@
"Vouer: %1$s"
"Legstukke"
"Muurpapiere"
- "Home-instellings"
+ "Tuis-instellings"
"Gedeaktiveer deur jou administrateur"
- "Oorsig"
"Laat toe dat tuisskerm gedraai word"
"Wanneer foon gedraai word"
- "Huidige vertooninstelling laat nie rotasie toe nie"
"Kennisgewingkolle"
"Aan"
"Af"
"Kennisgewingtoegang word benodig"
"Skakel programkennisgewings vir %1$s aan om kennisgewingkolle te sien"
"Verander instellings"
+ "Wys kennisgewingkolle"
"Voeg ikoon by tuisskerm"
"Vir nuwe programme"
"Verander ikoon se vorm"
+ "op tuisskerm"
"Gebruik stelselverstek"
"Vierkant"
"Sirkelvierkant"
@@ -99,6 +108,8 @@
"%1$s laai tans af, %2$s voltooid"
"%1$s wag tans om te installeer"
"%1$s-legstukke"
+ "Legstukkelys"
+ "Legstukkelys is toegemaak"
"Voeg by tuisskerm"
"Skuif item hierheen"
"Item is by tuisskerm gevoeg"
@@ -114,9 +125,6 @@
"Skep vouer met: %1$s"
"Vouer geskep"
"Skuif na tuisskerm"
- "Skuif skerm na links"
- "Skuif skerm na regs"
- "Skerm is geskuif"
"Verander grootte"
"Vermeerder breedte"
"Vermeerder hoogte"
@@ -124,8 +132,16 @@
"Verminder hoogte"
"Legstukgrootte is verander na breedte %1$s hoogte %2$s"
"Kortpaaie"
- "%1$d kortpaaie vir %2$s"
- "%1$d kortpaaie en %2$d kennisgewings vir %3$s"
+ "Kortpaaie en kennisgewings"
"Maak toe"
"Kennisgewing is toegemaak"
+ "Persoonlik"
+ "Werk"
+ "Werkprofiel"
+ "Kry werkprogramme hier"
+ "Elke werkprogram het \'n kenteken en word deur jou organisasie veilig gehou. Skuif programme na jou tuisskerm toe vir makliker toegang."
+ "Bestuur deur jou organisasie"
+ "Kennisgewings en programme is af"
+ "Maak toe"
+ "Toe"
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 293b452f68..921fbd9162 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -40,13 +40,18 @@
"ከ«%1$s» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"
"ተጨማሪ መተግበሪያዎች ይፈልጉ"
"ማሳወቂያዎች"
+ "አንድ አቋራጭ ለመውሰድ ነክተው ይያዙ።"
+ "አንድ አቋራጭ ለመውሰድ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።"
"በዚህ መነሻ ማያ ገጽ ላይ ምንም ቦታ የለም።"
"በተወዳጆች መሣቢያ ውስጥ ተጨማሪ ቦታ የለም"
"የመተግበሪያዎች ዝርዝር"
+ "የግል መተግበሪያዎች ዝርዝር"
+ "የሥራ መተግበሪያዎች ዝርዝር"
"መነሻ"
"አስወግድ"
"አራግፍ"
"የመተግበሪያ መረጃ"
+ "ጫን"
"አቋራጮችን ይጭናል"
"መተግበሪያው ያለተጠቃሚ ጣልቃ ገብነት አቋራጭ እንዲያክል ያስችለዋል።"
"የመነሻ ቅንብሮች እና አቋራጮችን ያነባል"
@@ -59,6 +64,10 @@
"ይህ የስርዓት መተግበሪያ ነው እና ማራገፍ አይቻልም።"
"ስም-አልባ አቃፊ"
"%1$s ተሰናክሏል"
+
+ - %1$s፣ %2$d ማሳወቂያዎች አለው
+ - %1$s፣ %2$d ማሳወቂያዎች አለው
+
"ገጽ %1$d ከ%2$d"
"መነሻ ማያ ገጽ %1$d ከ%2$d"
"አዲስ የመነሻ ማያ ገጽ"
@@ -72,19 +81,19 @@
"የግድግዳ ወረቀቶች"
"የመነሻ ቅንብሮች"
"በእርስዎ አስተዳዳሪ የተሰናከለ"
- "አጠቃላይ ዕይታ"
"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"
"ስልኩ ሲዞር"
- "የአሁኑ የማሳያ ቅንብር ማሽከርከርን አይፈቅድም"
"የማሳወቂያ ነጥቦች"
"በርቷል"
"ጠፍቷል"
"የማሳወቂያ መዳረሻ ያስፈልጋል"
"የማሳወቂያ ነጥቦችን ለማሳየት የመተግብሪያ ማሳወቂያዎችን ለ%1$s ያብሩ"
"ቅንብሮችን ቀይር"
+ "የማሳወቂያ ነጥቦችን አሳይ"
"አዶ ወደ የመነሻ ማያ ገጽ አክል"
"ለአዲስ መተግበሪያዎች"
"የአዶ ቅርፅ ለውጥ"
+ "በመነሻ ማያ ገጽ ላይ"
"የሥርዓቱን ነባሪ ተጠቀም"
"ካሬ"
"Squircle"
@@ -99,6 +108,8 @@
"%1$s በመውረድ ላይ፣ %2$s ተጠናቋል"
"%1$s ለመጫን በመጠበቅ ላይ"
"%1$s ንዑስ ፕሮግራሞች"
+ "የመግብሮች ዝርዝር"
+ "የመግብሮች ዝርዝር ተዘግቷል"
"ወደ መነሻ ማያ ገጽ ያክሉ"
"ንጥልን ወደዚህ ውሰድ"
"ወደ መነሻ ማያ ገጽ ንጥል ታክሏል"
@@ -114,9 +125,6 @@
"አቃፊ ፍጠር ከዚህ ጋር፦ %1$s"
"አቃፊ ተፈጥሮዋል"
"ወደ መነሻ ማያ ገጽ አንቀሳቅስ"
- "ማያ ገጽን ወደ ግራ አንቀሳቅስ"
- "ማያ ገጽን ወደ ቀኝ አንቀሳቅስ"
- "ማያ ገጽ ተንቀሳቅሷል"
"መጠን ቀይር"
"ስፋት ጨምር"
"ቁመት ጨምር"
@@ -124,8 +132,16 @@
"ቁመት ይቀንሱ"
"የመግብር መጠን ወደ ስፋት %1$s ቁመት %2$s ተለውጧል"
"አቋራጮች"
- "%1$d የ%2$s አቋራጮች"
- "%1$d አቋራጮች እና %2$d ማሳወቂያዎች ለ%3$s"
+ "አቋራጮች እና ማሳወቂያዎች"
"አሰናብት"
"ማሳወቂያ ተሰናብቷል"
+ "የግል"
+ "ሥራ"
+ "የሥራ መገለጫ"
+ "የስራ መተግበሪያዎችን እዚህ ያግኙ"
+ "እያንዳንዱ የሥራ መተግበሪያ ባጅ አለው፣ እና በድርጅትዎ ደህንነቱ ተጠብቋል። ለቀለለ መዳረሻ መተግበሪያዎችን ወደ የእርስዎ መነሻ ማያ ገጽ ይውሰዷቸው።"
+ "በእርስዎ ድርጅት የሚተዳደር"
+ "ማሳወቂያዎች እና መተግበሪያዎች ጠፍተዋል"
+ "ዝጋ"
+ "ዝግ"
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 6447bf0150..ecf32d4f77 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -24,29 +24,34 @@
"العمل"
"لم يتم تثبيت التطبيق."
"التطبيق ليس متاحًا"
- "تم تعطيل التطبيق الذي تم تنزيله في الوضع الآمن"
- "الأدوات معطلة في الوضع الآمن"
+ "تم إيقاف التطبيق الذي تم تنزيله في الوضع الآمن"
+ "الأدوات غير مفعّلة في الوضع الآمن"
"الاختصار غير متاح"
"الشاشة الرئيسية"
"الإجراءات المخصّصة"
"المس مع الاستمرار لاختيار إحدى الأدوات."
- "انقر نقرًا مزدوجًا مع الاستمرار لاختيار أداة أو استخدم الإجراءات المخصصة."
+ "انقر مرّتين مع الاستمرار لاختيار أداة أو استخدم الإجراءات المخصصة."
"%1$d × %2$d"
"العرض %1$d الطول %2$d"
- "المس مع الاستمرار للإضافة يدويًا"
- "إضافة تلقائيًا"
+ "انقر مع الاستمرار لإضافة العنصر يدويًا"
+ "الإضافة تلقائيًا"
"بحث في التطبيقات"
"جارٍ تحميل التطبيقات…"
"لم يتم العثور على أي تطبيقات تتطابق مع \"%1$s\""
"البحث عن مزيد من التطبيقات"
"الإشعارات"
+ "انقر مع الاستمرار لاختيار اختصار."
+ "يمكنك النقر مرّتين مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."
"ليس هناك مساحة أخرى في هذه الشاشة الرئيسية."
"لا يوجد المزيد من الحقول في علبة المفضلة"
"قائمة التطبيقات"
+ "قائمة التطبيقات الشخصية"
+ "قائمة تطبيقات العمل"
"الرئيسية"
"إزالة"
"إلغاء التثبيت"
"معلومات عن التطبيق"
+ "تثبيت"
"تثبيت اختصارات"
"للسماح لتطبيق ما بإضافة اختصارات بدون تدخل المستخدم."
"قراءة إعدادات واختصارات الشاشة الرئيسية"
@@ -58,7 +63,15 @@
"الإعداد"
"هذا تطبيق نظام وتتعذر إزالته."
"مجلد بدون اسم"
- "تم تعطيل %1$s"
+ "تم إيقاف %1$s"
+
+ - %1$s، به %2$d إشعار
+ - %1$s، به إشعاران (%2$d)
+ - %1$s، به %2$d إشعارات
+ - %1$s، به %2$d إشعارًا
+ - %1$s، به %2$d إشعار
+ - %1$s، به %2$d إشعار
+
"الصفحة %1$d من %2$d"
"الشاشة الرئيسية %1$d من %2$d"
"صفحة الشاشة الرئيسية الجديدة"
@@ -71,21 +84,21 @@
"الأدوات"
"الخلفيات"
"إعدادات الصفحة الرئيسية"
- "عطَّل المشرف هذه الميزة"
- "نظرة عامة"
+ "أوقف المشرف هذه الميزة"
"السماح بتدوير الشاشة الرئيسية"
"عند تدوير الهاتف"
- "لا يسمح إعداد العرض الحالي بالتدوير"
"نقاط الإشعارات"
"قيد التشغيل"
- "قيد الإيقاف"
- "يلزم تمكين الوصول إلى الإشعارات"
+ "غير مفعّل"
+ "يلزم تفعيل الوصول إلى الإشعارات"
"لعرض نقاط الإشعارات، يجب تشغيل إشعارات التطبيق في %1$s"
"تغيير الإعدادات"
+ "عرض نقاط الإشعارات"
"إضافة رمز إلى الشاشة الرئيسية"
"للتطبيقات الجديدة"
"تغيير شكل الرمز"
- "استخدام الإعداد الافتراضي للنظام"
+ "على الشاشة الرئيسية"
+ "استخدام الإعداد التلقائي للنظام"
"مربّع"
"رمز دائري مربّع"
"دائرة"
@@ -99,6 +112,8 @@
"جارٍ تنزيل %1$s، اكتمل %2$s"
"%1$s في انتظار التثبيت"
"أدوات %1$s"
+ "قائمة الأدوات"
+ "تم إغلاق قائمة الأدوات."
"إضافة إلى الشاشة الرئيسية"
"نقل العنصر إلى هنا"
"تمت إضافة العنصر إلى الشاشة الرئيسية"
@@ -114,9 +129,6 @@
"إنشاء مجلد يتضمن: %1$s"
"تم إنشاء المجلد"
"نقل إلى الشاشة الرئيسية"
- "نقل الشاشة إلى اليسار"
- "نقل الشاشة إلى اليمين"
- "تم نقل الشاشة"
"تغيير حجم"
"زيادة العرض"
"زيادة الارتفاع"
@@ -124,8 +136,16 @@
"تقليل الارتفاع"
"تم تغيير حجم الأداة إلى العرض %1$s والارتفاع %2$s"
"الاختصارات"
- "%1$d اختصار لتطبيق %2$s"
- "هناك %1$d اختصار و%2$d إشعار عن %3$s"
+ "الاختصارات والإشعارات"
"تجاهل"
"تم تجاهل الإشعار"
+ "شخصية"
+ "للعمل"
+ "الملف الشخصي للعمل"
+ "البحث عن تطبيقات العمل هنا"
+ "يحتوي كل تطبيق للعمل على شارة ويظل تحت حماية مؤسستك. يمكنك نقل التطبيقات إلى شاشتك الرئيسية لتسهيل الوصول إليها."
+ "ملف شخصي للعمل تديره مؤسستك"
+ "الإشعارات والتطبيقات متوقفة."
+ "إغلاق"
+ "تمّ الإغلاق"
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
new file mode 100644
index 0000000000..5c896e4f24
--- /dev/null
+++ b/res/values-as/strings.xml
@@ -0,0 +1,149 @@
+
+
+
+
+ "Launcher3"
+
+ "কৰ্মস্থান"
+ "এপটো ইনষ্টল কৰা নহ\'ল।"
+ "এপটো নাই"
+ "ডাউনল\'ড কৰা এপটোক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ\'ল"
+ "ৱিজেটবোৰক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ\'ল"
+ "শ্বৰ্টকাট নাই"
+ "গৃহ স্ক্ৰীণ"
+ "উপযোগিতা অনুসৰি কৰা কাৰ্যবিলাক"
+ "কোনো ৱিজেট বাছনি কৰিবলৈ স্পৰ্শ কৰি থাকক।"
+ "কোনো ৱিজেট বাছনি কৰিবলৈ অথবা উপযোগিতা অনুসৰি কাৰ্যবিলাক ব্য়ৱহাৰ কৰিবলৈ দুবাৰ টিপি থাকক।"
+ "%1$d × %2$d"
+ "%1$d বহল x %2$d ওখ"
+ "মেনুৱেলভাৱে ৰাখিবলৈ স্পৰ্শ কৰি থাকক"
+ "স্বয়ংক্ৰিয়ভাবে যোগ কৰক"
+ "এপসমূহ সন্ধান কৰক"
+ "এপসমূহ ল’ড কৰি থকা হৈছে…"
+ "\"%1$s\"ৰ সৈতে মিলা কোনো এপ্ বিচাৰি পোৱা নগ\'ল"
+ "আৰু অধিক এপবোৰ সন্ধান কৰক"
+ "জাননীসমূহ"
+ "কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ স্পৰ্শ কৰি হেঁচি ধৰক।"
+ "কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ দুবাৰ টিপি হেঁচি ধৰক, বা নিজৰ উপযোগিতা অনুসৰি সৃষ্টি কৰা কাৰ্যসমূহ ব্যৱহাৰ কৰক।"
+ "এই গৃহ স্ক্ৰীণত আৰু বেছি ঠাই নাই।"
+ "পছন্দৰ ট্ৰে\'ত আৰু বেছি ঠাই নাই"
+ "এপৰ সূচী"
+ "ব্যক্তিগত এপৰ তালিকা"
+ "কৰ্মস্থানৰ এপৰ তালিকা"
+ "গৃহপৃষ্ঠা"
+ "আঁতৰাওক"
+ "আনইনষ্টল কৰক"
+ "এপ সম্পৰ্কীয় তথ্য"
+ "ইনষ্টল কৰক"
+ "শ্বৰ্টকাট ইনষ্টল কৰিব পাৰে"
+ "ব্য়ৱহাৰকাৰীৰ হস্তক্ষেপ অবিহনেই কোনো এপক শ্বৰ্টকাটবোৰ যোগ কৰাৰ অনুমতি দিয়ে।"
+ "গৃহ ছেটিং আৰু শ্বৰ্টকাটবোৰ পঢ়িব পাৰে"
+ "এপটোক গৃহ পৃষ্ঠাত ছেটিং আৰু শ্বৰ্টকাটসমূহ পঢ়াৰ অনুমতি দিয়ে।"
+ "গৃহ ছেটিং আৰু শ্বৰ্টকাটবোৰ লিখিব পাৰে"
+ "এপটোক গৃহ পৃষ্ঠাত ছেটিং আৰু শ্বৰ্টকাটসমূহ সলনি কৰাৰ অনুমতি দিয়ে।"
+ "%1$sক ফ\'ন কলবোৰ কৰাৰ অনুমতি দিয়া হোৱা নাই"
+ "ৱিজেট ল\'ড কৰাত সমস্য়া"
+ "ছেটআপ কৰক"
+ "এইটো এটা ছিষ্টেম এপ আৰু ইয়াক আনইনষ্টল কৰিব নোৱৰি"
+ "নামবিহীন ফ\'ল্ডাৰ"
+ "%1$s অক্ষম কৰা হ\'ল"
+
+ - %1$sৰ %2$dটা জাননী আছে
+ - %1$sৰ %2$dটা জাননী আছে
+
+ "%2$dৰ %1$d পৃষ্ঠা"
+ "গৃহ স্ক্ৰীণ %2$dৰ %1$d"
+ "গৃহ স্ক্ৰীণৰ নতুন পৃষ্ঠা"
+ "ফ’ল্ডাৰ খোলা হ\'ল, %1$d x %2$d"
+ "ফ\'ল্ডাৰ বন্ধ কৰিবলৈ টিপক"
+ "সলনি কৰা নাম ছেভ কৰিবলৈ টিপক"
+ "ফ\'ল্ডাৰ বন্ধ কৰা হ\'ল"
+ "ফ\'ল্ডাৰৰ নাম সলনি কৰি %1$s কৰা হৈছে"
+ "ফ’ল্ডাৰ: %1$s"
+ "ৱিজেটসমূহ"
+ "ৱালপেপাৰসমূহ"
+ "গৃহ ছেটিংসমূহ"
+ "আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে"
+ "গৃহ স্ক্ৰীণ ঘূৰোৱাৰ অনুমতি দিয়ক"
+ "ফ\'নটো যেতিয়া ঘূৰোৱা হয়"
+ "জাননী সম্পৰ্কীয় বিন্দুবোৰ"
+ "অন অৱস্থাত আছে"
+ "অফ অৱস্থাত আছে"
+ "জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন"
+ "জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ %1$sৰ বাবে এপৰ জাননীসমূহ অন কৰক"
+ "ছেটিংসমূহ সলনি কৰক"
+ "জাননী বিন্দুসমূহ দেখুৱাওক"
+ "গৃহ স্ক্ৰীণত আইকনটো যোগ কৰক"
+ "নতুন এপসমূহৰ বাবে"
+ "আইকনৰ আকৃতি সলনি কৰক"
+ "গৃহ স্ক্ৰীণত"
+ "ছিষ্টেম ডিফ\'ল্ট ব্য়ৱহাৰ কৰক"
+ "বৰ্গাকাৰ"
+ "বৰ্গবৃত্তাকাৰ"
+ "পৰিচিত মানুহৰ গোট"
+ "চকুপানীৰ টোপাল"
+ "আইকনৰ আকৃতিত কৰা পৰিবৰ্তনবোৰ প্ৰয়োগ কৰি থকা হৈছে"
+ "অজ্ঞাত"
+ "আঁতৰাওক"
+ "সন্ধান কৰক"
+ "এই এপটো ইনষ্টল কৰা হোৱা নাই"
+ "এই আইকনৰ এপটো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপটো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।"
+ "%1$s ডাউনল\'ড কৰি থকা হৈছে, %2$s সম্পূৰ্ণ হ\'ল"
+ "%1$s ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে"
+ "%1$s ৱিজেট"
+
+
+
+
+ "গৃহ স্ক্ৰীণত যোগ কৰক"
+ "বস্তুটো ইয়ালৈ স্থানান্তৰ কৰক"
+ "বস্তুটো গৃহ স্ক্ৰীণত যোগ কৰা হ\'ল"
+ "বস্তুটো আঁতৰোৱা হ\'ল"
+ "বস্তু স্থানান্তৰ কৰক"
+ "শাৰী %1$s স্তম্ভ %2$sলৈ স্থানান্তৰিত কৰক"
+ "পছন্দৰ অৱস্থান %1$sলৈ স্থানান্তৰিত কৰক"
+ "পছন্দৰ অৱস্থান %1$sলৈ স্থানান্তৰিত কৰক"
+ "বস্তুটো স্থানান্তৰ কৰা হ\'ল"
+ "ফ\'ল্ডাৰত যোগ কৰক: %1$s"
+ "%1$sসহ ফ\'ল্ডাৰত যোগ কৰক"
+ "বস্তুটো ফ\'ল্ডাৰত যোগ কৰা হ\'ল"
+ "%1$s: ৰ জৰিয়তে ফ\'ল্ডাৰ সৃষ্টি কৰক"
+ "ফ\'ল্ডাৰ সৃষ্টি কৰা হ\'ল"
+ "হ\'ম স্ক্ৰীণলৈ স্থানান্তৰ কৰক"
+ "আকাৰ সলনি কৰক"
+ "প্ৰস্থ বৃদ্ধি কৰক"
+ "উচ্চতা বৃদ্ধি কৰক"
+ "প্ৰস্থ হ্ৰাস কৰক"
+ "উচ্চতা হ্ৰাস কৰক"
+ "ৱিজেটৰ আকাৰ সলনি কৰি প্ৰস্থ %1$s আৰু উচ্চতা %2$s কৰা হ\'ল"
+ "শ্বৰ্টকাটসমূহ"
+ "শ্বৰ্টকাট আৰু জাননীসমূহ"
+ "অগ্ৰাহ্য কৰক"
+ "জাননী অগ্ৰাহ্য কৰা হৈছে"
+ "ব্যক্তিগত"
+ "কৰ্মস্থান"
+ "কৰ্মস্থানৰ প্ৰ\'ফাইল"
+ "ইয়াত কৰ্মস্থানৰ এপ্ বিচাৰি পাওক"
+ "কৰ্মস্থানৰ প্ৰতিটো এপৰে একোটা প্ৰতীক আছে আৰু তাক আপোনাৰ প্ৰতিষ্ঠানে সুৰক্ষিত কৰি ৰাখে। ব্যৱহাৰ কৰাত সুবিধা হ\'বলৈ এপসমূহ আপোনাৰ গৃহ স্ক্ৰীণলৈ স্থানান্তৰ কৰক।"
+ "আপোনাৰ প্ৰতিষ্ঠানৰ দ্বাৰা পৰিচালিত"
+ "জাননী আৰু এপসমূহ অফ হৈ আছে"
+ "বন্ধ কৰক"
+ "বন্ধ"
+
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000000..ed86f91552
--- /dev/null
+++ b/res/values-az-rAZ/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "İş"
+ "Tətbiq quraşdırılmayıb."
+ "Tətbiq əlçatmazdır"
+ "Güvənli rejimdə icazə verilməyən tətbiq endirildi"
+ "Vidcetlər Güvənli rejimdə deaktiv edilib"
+ "Qısayol əlçatan deyil"
+ "Əsas ekran"
+ "Fərdi əməliyyatlar"
+ "Vidceti götürmək üçün toxunub saxlayın."
+ "Vidceti götürmək üçün & iki dəfə toxunub saxlayın və ya fərdi fəaliyyətləri istifadə edin."
+ "%1$d × %2$d"
+ "%2$d hündürlük %1$d enində"
+ "Manual olaraq yerləşdirmək üçün toxunaraq basıb saxlayın"
+ "Avtomatik əlavə edin"
+ "Tətbiqləri axtarın"
+ "Tətbiqlər yüklənir…"
+ "%1$s sorğusuna uyğun tətbiq tapılmadı"
+ "Daha çox tətbiq üçün axtarış edin"
+ "Bildirişlər"
+ "Qısayolu seçmək üçün basıb saxlayın."
+ "Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."
+ "Bu Əsas ekranda boş yer yoxdur."
+ "Favoritlər-də yer yoxdur"
+ "Tətbiq siyahısı"
+ "Şəxsi tətbiqlərin siyahısı"
+ "İş tətbiqlərinin siyahısı"
+ "Əsas səhifə"
+ "Silin"
+ "Sistemdən sil"
+ "Tətbiq məlumatı"
+ "Quraşdırın"
+ "qısayolları quraşdır"
+ "Tətbiqə istifadəçi müdaxiləsi olmadan qısayolları əlavə etməyə icazə verir."
+ "Əsas Səhifə ayarlarını və qısayolları oxuyun"
+ "Tətbiqə Əsas Səhifədə parametrləri və qısayolları oxumağa icazə verir."
+ "Əsas Səhifə ayarlarını və qısayolları yazın"
+ "Tətbiqə Əsas Səhifədə ayarları və qısayolları dəyişməyə icazə verir."
+ "%1$s tətbiqinə telefon zəngləri etmək üçün icazə verilmir"
+ "Vidcet yükləmə problemi"
+ "Quraşdırma"
+ "Bu sistem tətbiqi olduğu üçün sistemdən silinə bilməz."
+ "Adsız Qovluq"
+ "%1$s deaktiv edildi"
+
+ - %1$s tətbiqində %2$d bildiriş var
+ - %1$s tətbiqində %2$d bildiriş var
+
+ "Səhifə %1$d of %2$d"
+ "Əsas Səhifə ekranı %1$d of %2$d"
+ "Yeni əsas ekran səhifəsi"
+ "Qovluq açıldı, %2$d hündürlük ilə %1$d enində"
+ "Qovluq bağlamaq üçün toxunun"
+ "Ad dəyişikliyini yadda saxlamaq üçün toxunun"
+ "Qovluq bağlıdır"
+ "Qovluq adı %1$s ilə dəyişdirildi"
+ "Qovluq: %1$s"
+ "Vidcet"
+ "Divar kağızları"
+ "Home ayarları"
+ "Admininiz tərəfindən deaktiv edilib"
+ "Əsas ekranın firlanmağına icazə verin"
+ "Telefon çevrilən zaman"
+ "Bildiriş nişanı"
+ "Aktiv"
+ "Deaktiv"
+ "Bildiriş girişi tələb edilir"
+ "Bildiriş Nöqtələrini göstərmək üçün %1$s bildirişlərini aktiv edin"
+ "Ayarları dəyişin"
+ "Bildiriş nöqtələrini göstərin"
+ "Əsas ekrana ikona əlavə edin"
+ "Yeni tətbiqlər üçün"
+ "İkona formasını dəyişin"
+ "Əsas səhifə ekranında"
+ "Sistem defoltu istifadə edin"
+ "Kvadrat"
+ "Kənarları dairəvi kvadrat"
+ "Çevrə"
+ "Gözyaşı damlası"
+ "İkona formasına etdiyiniz dəyişikliklər tətbiq edilir"
+ "Naməlum"
+ "Yığışdır"
+ "Axtarış"
+ "Bu tətbiq quraşdırılmayıb"
+ "Bu ikona üçün tətbiq quraşdırılmayıb. Onu silə bilərsiniz, və ya tətbiqi taparaq manual yol ilə quraşdıra bilərsiniz."
+ "%1$s endirilir, %2$s tamamlandı"
+ "%1$s yüklənmək üçün gözləyir"
+ "%1$s vidcetləri"
+ "Əsas ekrana əlavə edin"
+ "Elementi bura köçürün"
+ "Element əsas ekrana əlavə edildi"
+ "Element silindi"
+ "Elementi köçürün"
+ "Sıra %1$s sütun %2$s köçürün"
+ "%1$s mövqeyinə köçürün"
+ "%1$s sevimlilər mövqeyinə köçürün"
+ "Elementin yeri dəyişildi"
+ "Qovluğa əlavə edin: %1$s"
+ "%1$s adlı qovluğa əlavə edin"
+ "Element qovluğa əlavə edildi"
+ "Qovluq yaradın: %1$s"
+ "Qovluq yaradıldı"
+ "Əsas ekrana köçürün"
+ "Ölçüsünü dəyişin"
+ "Eni artırın"
+ "Hündürlüyü artırın"
+ "Eni azaldın"
+ "Hündürlüyü azaldın"
+ "Vidcetin eni %1$s hündürlüyü %2$s kimi ölçüləndirildi"
+ "Qısa yollar"
+ "%1$d üçün %2$s qısa yolu"
+ "%3$s üçün %1$d qısayol və %2$d bildiriş"
+ "Rədd edin"
+ "Bildiriş rədd edildi"
+ "Şəxsi"
+ "İş"
+ "İş profili"
+ "Burada iş tətbiqləri axtarın"
+ "Hər bir iş tətbiqində təşkilat tərəfindən qorunduğunu göstərən narıncı nişan var. Tətbiqləri daha asan giriş üçün Əsas Səhifə Ekranına köçürün."
+ "Təşkilatınız tərəfindən idarə olunur"
+ "Bildiriş və tətbiqlər deaktivdir"
+ "Bağlayın"
+ "Bağlıdır"
+
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 18f87bcf33..3b36f37b25 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -40,13 +40,18 @@
"%1$s sorğusuna uyğun tətbiq tapılmadı"
"Daha çox tətbiq üçün axtarış edin"
"Bildirişlər"
+ "Qısayolu seçmək üçün basıb saxlayın."
+ "Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."
"Bu Əsas ekranda boş yer yoxdur."
"Favoritlər-də yer yoxdur"
"Tətbiq siyahısı"
+ "Şəxsi tətbiqlərin siyahısı"
+ "İş tətbiqlərinin siyahısı"
"Əsas səhifə"
"Silin"
"Sistemdən sil"
"Tətbiq məlumatı"
+ "Quraşdırın"
"qısayolları quraşdır"
"Tətbiqə istifadəçi müdaxiləsi olmadan qısayolları əlavə etməyə icazə verir."
"Əsas Səhifə ayarlarını və qısayolları oxuyun"
@@ -59,6 +64,10 @@
"Bu sistem tətbiqi olduğu üçün sistemdən silinə bilməz."
"Adsız Qovluq"
"%1$s deaktiv edildi"
+
+ - %1$s tətbiqində %2$d bildiriş var
+ - %1$s tətbiqində %2$d bildiriş var
+
"Səhifə %1$d of %2$d"
"Əsas Səhifə ekranı %1$d of %2$d"
"Yeni əsas ekran səhifəsi"
@@ -72,19 +81,19 @@
"Divar kağızları"
"Home ayarları"
"Admininiz tərəfindən deaktiv edilib"
- "İcmal"
"Əsas ekranın firlanmağına icazə verin"
"Telefon çevrilən zaman"
- "Cari Ekran ayarı fırlatmağa icazə vermir"
"Bildiriş nişanı"
"Aktiv"
"Deaktiv"
"Bildiriş girişi tələb edilir"
"Bildiriş Nöqtələrini göstərmək üçün %1$s bildirişlərini aktiv edin"
"Ayarları dəyişin"
+ "Bildiriş nöqtələrini göstərin"
"Əsas ekrana ikona əlavə edin"
"Yeni tətbiqlər üçün"
"İkona formasını dəyişin"
+ "Əsas səhifə ekranında"
"Sistem defoltu istifadə edin"
"Kvadrat"
"Kənarları dairəvi kvadrat"
@@ -99,6 +108,8 @@
"%1$s endirilir, %2$s tamamlandı"
"%1$s yüklənmək üçün gözləyir"
"%1$s vidcetləri"
+ "Vidcet siyahısı"
+ "Vidcet siyahısı bağlandı"
"Əsas ekrana əlavə edin"
"Elementi bura köçürün"
"Element əsas ekrana əlavə edildi"
@@ -114,9 +125,6 @@
"Qovluq yaradın: %1$s"
"Qovluq yaradıldı"
"Əsas ekrana köçürün"
- "Ekranı sola köçürün"
- "Ekranı sağa köçürün"
- "Ekran köçürülüb"
"Ölçüsünü dəyişin"
"Eni artırın"
"Hündürlüyü artırın"
@@ -124,8 +132,16 @@
"Hündürlüyü azaldın"
"Vidcetin eni %1$s hündürlüyü %2$s kimi ölçüləndirildi"
"Qısa yollar"
- "%1$d üçün %2$s qısa yolu"
- "%3$s üçün %1$d qısayol və %2$d bildiriş"
+ "Qısayol və bildirişlər"
"Rədd edin"
"Bildiriş rədd edildi"
+ "Şəxsi"
+ "İş"
+ "İş profili"
+ "Burada iş tətbiqləri axtarın"
+ "Hər bir iş tətbiqində təşkilat tərəfindən qorunduğunu göstərən narıncı nişan var. Tətbiqləri daha asan giriş üçün Əsas Səhifə Ekranına köçürün."
+ "Təşkilatınız tərəfindən idarə olunur"
+ "Bildiriş və tətbiqlər deaktivdir"
+ "Bağlayın"
+ "Bağlıdır"
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 777512a966..3fb8bf50c5 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -40,13 +40,18 @@
"Nije pronađena nijedna aplikacija za „%1$s“"
"Pretraži još aplikacija"
"Obaveštenja"
+ "Dodirnite i zadržite da biste izabrali prečicu."
+ "Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje."
"Nema više prostora na ovom početnom ekranu."
"Nema više prostora na traci Omiljeno"
"Lista aplikacija"
+ "Lista ličnih aplikacija"
+ "Lista poslovnih aplikacija"
"Početna"
"Ukloni"
"Deinstaliraj"
"Inform. o aplikaciji"
+ "Instaliraj"
"instaliranje prečica"
"Dozvoljava aplikaciji da dodaje prečice bez intervencije korisnika."
"čitanje podešavanja i prečica na početnom ekranu"
@@ -59,6 +64,11 @@
"Ovo je sistemska aplikacija i ne može da se deinstalira."
"Neimenovani direktorijum"
"Aplikacija %1$s je onemogućena"
+
+ - %1$s ima %2$d obaveštenje
+ - %1$s ima %2$d obaveštenja
+ - %1$s ima %2$d obaveštenja
+
"%1$d. stranica od %2$d"
"%1$d. početni ekran od %2$d"
"Nova stranica početnog ekrana"
@@ -72,19 +82,19 @@
"Pozadine"
"Podešavanja početnog ekrana"
"Administrator je onemogućio"
- "Pregled"
"Dozvoli rotaciju početnog ekrana"
"Kada se telefon rotira"
- "Aktuelno podešavanje prikaza ne dozvoljava rotaciju"
"Tačke za obaveštenja"
"Uključeno"
"Isključeno"
"Potreban je pristup za obaveštenja"
"Da biste prikazali tačke za obaveštenja, uključite obaveštenja za aplikaciju %1$s"
"Promenite podešavanja"
+ "Prikazuj tačke za obaveštenja"
"Dodaj ikonu na početni ekran"
"Za nove aplikacije"
"Promenite oblik ikona"
+ "na početnom ekranu"
"Koristi podrazumevano sistemsko podešavanje"
"Kvadrat"
"Zaobljeni kvadrat"
@@ -99,6 +109,8 @@
"%1$s se preuzima, završeno je %2$s"
"%1$s čeka na instaliranje"
"Vidžeti za %1$s"
+ "Lista vidžeta"
+ "Lista vidžeta je zatvorena"
"Dodaj na početni ekran"
"Premesti stavku ovde"
"Stavka je dodata na početni ekran"
@@ -114,9 +126,6 @@
"Napravite direktorijum sa: %1$s"
"Direktorijum je napravljen"
"Premesti na početni ekran"
- "Pomeri ekran ulevo"
- "Pomeri ekran udesno"
- "Ekran je pomeren"
"Promeni veličinu"
"Povećaj širinu"
"Povećaj visinu"
@@ -124,8 +133,16 @@
"Smanji visinu"
"Veličina vidžeta je promenjena na širinu %1$s i visinu %2$s"
"Prečice"
- "%1$d prečice(a) za %2$s"
- "Prečice (%1$d) i obaveštenja (%2$d) za %3$s"
+ "Prečice i obaveštenja"
"Odbaci"
"Obaveštenje je odbačeno"
+ "Lične"
+ "Poslovne"
+ "Profil za Work"
+ "Pronađite poslovne aplikacije ovde"
+ "Svaka poslovna aplikacija ima značku i štiti je vaša organizacija. Premestite aplikacije na početni ekran da biste im lakše pristupali."
+ "Ovim upravlja organizacija"
+ "Obaveštenja i aplikacije su isključeni"
+ "Zatvori"
+ "Zatvoreno"
diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml
new file mode 100644
index 0000000000..399ae763e7
--- /dev/null
+++ b/res/values-be-rBY/strings.xml
@@ -0,0 +1,148 @@
+
+
+
+
+ "Launcher3"
+
+ "Працоўная"
+ "Праграма не ўсталявана."
+ "Праграма недаступная"
+ "Спампаваная праграма адключана ў Бяспечным рэжыме"
+ "Віджэты адключаны ў Бяспечным рэжыме"
+ "Ярлык недаступны"
+ "Галоўны экран"
+ "Спецыяльныя дзеянні"
+ "Дакраніцеся і ўтрымлiвайце віджэт, каб выбр. яго."
+ "Дакраніцеся двойчы і ўтрымлівайце, каб выбраць віджэт або выкарыстоўваць карыстальніцкія дзеянні."
+ "%1$d × %2$d"
+ "Шырына: %1$d, вышыня: %2$d"
+ "Каб размясціць уручную, дакраніцеся і ўтрымлівайце"
+ "Дадаць аўтаматычна"
+ "Пошук праграм"
+ "Праграмы загружаюцца…"
+ "Праграм, якія адпавядаюць запыту \"%1$s\", не знойдзена"
+ "Шукаць іншыя праграмы"
+ "Апавяшчэнні"
+ "Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."
+ "Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."
+ "На гэтым Галоўным экране больш няма месца."
+ "У латку \"Абранае\" больш няма месца"
+ "Спіс праграм"
+ "Спіс персанальных праграм"
+ "Спіс працоўных праграм"
+ "Галоўная"
+ "Выдаліць"
+ "Выдаліць"
+ "Звесткі пра праграмы"
+ "Усталяваць"
+ "усталёўваць ярлыкі"
+ "Дазваляе праграмам дадаваць ярлыкі без умяшання карыстальніка."
+ "счытваць налады і ярлыкі на Галоўнай старонцы"
+ "Дазваляе праграме счытваць налады і ярлыкі на Галоўнай старонцы."
+ "запісваць налады і ярлыкі на галоўнай старонцы"
+ "Дазваляе праграме змяняць налады і ярлыкі на Галоўнай старонцы."
+ "%1$s не мае дазволу на здзяйсненне тэлефонных званкоў"
+ "Праблема загрузкі віджэта"
+ "Наладжванне"
+ "Гэта сістэмная праграма, яе нельга выдаліць."
+ "Папка без назвы"
+ "%1$s адключана"
+
+ - %1$s: ёсць %2$d апавяшчэнне
+ - %1$s: ёсць %2$d апавяшчэнні
+ - %1$s: ёсць %2$d апавяшчэнняў
+ - %1$s: ёсць %2$d апавяшчэння
+
+ "Старонка %1$d з %2$d"
+ "Галоўны экран %1$d з %2$d"
+ "Новая старонка галоўнага экрана"
+ "Папка адкрыта, %1$d на %2$d"
+ "Краніце, каб закрыць папку"
+ "Краніце, каб захаваць новую назву"
+ "Папка закрыта"
+ "Папка перайменавана ў %1$s"
+ "Папка: %1$s"
+ "Віджэты"
+ "Шпалеры"
+ "Налады галоўнага экрана"
+ "Адключаная адміністратарам"
+ "Дазволіць паварот галоўнага экрана"
+ "Пры павароце тэлефона"
+ "Значкі апавяшчэнняў"
+ "Уключана"
+ "Выключана"
+ "Патрабуецца доступ да апавяшчэнняў"
+ "Каб паказваліся значкі апавяшчэнняў, уключыце апавяшчэнні праграм для %1$s"
+ "Змяніць налады"
+ "Паказаць значкі апавяшчэнняў"
+ "Дадаць значок на Галоўны экран"
+ "Для новых праграм"
+ "Змяніць форму значка"
+ "на галоўным экране"
+ "Выкарыстоўваць стандартныя формы"
+ "Квадрат"
+ "Прамавугольнік са скругленымі вугламі"
+ "Круг"
+ "Сляза"
+ "Змены формы значка прымяняюцца"
+ "Невядома"
+ "Выдаліць"
+ "Шукаць"
+ "Гэта праграма не ўсталявана"
+ "Праграма для гэтага значка не ўсталявана. Вы можаце выдаліць яе або выканаць пошук і ўсталяваць яе ўручную."
+ "Ідзе спампоўка %1$s, %2$s завершана"
+ "%1$s чакае ўсталёўкі"
+ "Віджэты %1$s"
+ "Дадаць на Галоўны экран"
+ "Перамясціць элемент сюды"
+ "Элемент дададзены на галоўны экран"
+ "Элемент выдалены"
+ "Перамясціць элемент"
+ "Перамясціць у радок %1$s слупок %2$s"
+ "Перамясціць у пазіцыю %1$s"
+ "Перамясціць у абранае, у пазіцыю %1$s"
+ "Элемент перамешчаны"
+ "Дадаць у папку: %1$s"
+ "Дадаць у папку з %1$s"
+ "Элемент дададзены ў папку"
+ "Стварыць папку з: %1$s"
+ "Папка створана"
+ "Перамясціць на Галоўны экран"
+ "Змяніць памер"
+ "Павялічыць шырыню"
+ "Павялічыць вышыню"
+ "Паменшыць шырыню"
+ "Паменшыць вышыню"
+ "Памеры віджэта зменены на: шырыня %1$s, вышыня %2$s"
+ "Ярлыкі"
+ "Ярлыкі (%1$d) для %2$s"
+ "Ярлыкі (%1$d) і апавяшчэнні (%2$d) для %3$s"
+ "Адхіліць"
+ "Апавяшчэнне адхілена"
+ "Асабістыя"
+ "Праца"
+ "Працоўны профіль"
+ "Знайдзіце працоўныя праграмы тут"
+ "Кожная працоўная праграма мае значок і знаходзіцца пад аховай вашай арганізацыі. Для больш простага доступу перамясціце праграмы на Галоўны экран."
+ "Пад кіраваннем вашай арганізацыі"
+ "Апавяшчэнні і праграмы выключаны"
+ "Закрыць"
+ "Закрытыя"
+
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 0a31ddf7c1..59a8f1fa2b 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -40,13 +40,18 @@
"Праграм, якія адпавядаюць запыту \"%1$s\", не знойдзена"
"Шукаць іншыя праграмы"
"Апавяшчэнні"
+ "Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."
+ "Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."
"На гэтым Галоўным экране больш няма месца."
"У латку \"Абранае\" больш няма месца"
"Спіс праграм"
+ "Спіс персанальных праграм"
+ "Спіс працоўных праграм"
"Галоўная"
"Выдаліць"
"Выдаліць"
"Звесткі пра праграмы"
+ "Усталяваць"
"усталёўваць ярлыкі"
"Дазваляе праграмам дадаваць ярлыкі без умяшання карыстальніка."
"счытваць налады і ярлыкі на Галоўнай старонцы"
@@ -59,6 +64,12 @@
"Гэта сістэмная праграма, яе нельга выдаліць."
"Папка без назвы"
"%1$s адключана"
+
+ - %1$s: ёсць %2$d апавяшчэнне
+ - %1$s: ёсць %2$d апавяшчэнні
+ - %1$s: ёсць %2$d апавяшчэнняў
+ - %1$s: ёсць %2$d апавяшчэння
+
"Старонка %1$d з %2$d"
"Галоўны экран %1$d з %2$d"
"Новая старонка галоўнага экрана"
@@ -72,19 +83,19 @@
"Шпалеры"
"Налады галоўнага экрана"
"Адключаная адміністратарам"
- "Агляд"
"Дазволіць паварот галоўнага экрана"
"Пры павароце тэлефона"
- "Бягучая налада дысплэя не прадугледжвае паварот"
"Значкі апавяшчэнняў"
"Уключана"
"Выключана"
"Патрабуецца доступ да апавяшчэнняў"
"Каб паказваліся значкі апавяшчэнняў, уключыце апавяшчэнні праграм для %1$s"
"Змяніць налады"
+ "Паказаць значкі апавяшчэнняў"
"Дадаць значок на Галоўны экран"
"Для новых праграм"
"Змяніць форму значка"
+ "на галоўным экране"
"Выкарыстоўваць стандартныя формы"
"Квадрат"
"Прамавугольнік са скругленымі вугламі"
@@ -99,6 +110,8 @@
"Ідзе спампоўка %1$s, %2$s завершана"
"%1$s чакае ўсталёўкі"
"Віджэты %1$s"
+ "Спіс віджэтаў"
+ "Спіс віджэтаў закрыты"
"Дадаць на Галоўны экран"
"Перамясціць элемент сюды"
"Элемент дададзены на галоўны экран"
@@ -114,9 +127,6 @@
"Стварыць папку з: %1$s"
"Папка створана"
"Перамясціць на Галоўны экран"
- "Перамясціць экран налева"
- "Перамясціць экран направа"
- "Экран перамешчаны"
"Змяніць памер"
"Павялічыць шырыню"
"Павялічыць вышыню"
@@ -124,8 +134,16 @@
"Паменшыць вышыню"
"Памеры віджэта зменены на: шырыня %1$s, вышыня %2$s"
"Ярлыкі"
- "Ярлыкі (%1$d) для %2$s"
- "Ярлыкі (%1$d) і апавяшчэнні (%2$d) для %3$s"
+ "Ярлыкі і апавяшчэнні"
"Адхіліць"
"Апавяшчэнне адхілена"
+ "Асабістыя"
+ "Праца"
+ "Працоўны профіль"
+ "Знайдзіце працоўныя праграмы тут"
+ "Кожная працоўная праграма мае значок і знаходзіцца пад аховай вашай арганізацыі. Для больш простага доступу перамясціце праграмы на Галоўны экран."
+ "Пад кіраваннем вашай арганізацыі"
+ "Апавяшчэнні і праграмы выключаны"
+ "Закрыць"
+ "Закрытыя"
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 3e05e0be57..47825f6bd0 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -40,13 +40,18 @@
"Няма намерени приложения, съответстващи на „%1$s“"
"Търсене на още приложения"
"Известия"
+ "Докоснете и задръжте за избор на пряк път."
+ "Докоснете двукратно и задръжте за избор на пряк път или използвайте персонализирани действия."
"На този начален екран няма повече място."
"Няма повече място в областта с любимите"
"Списък с приложения"
+ "Списък с лични приложения"
+ "Списък със служебни приложения"
"Начало"
"Премахване"
"Деинсталиране"
"Данни за прилож."
+ "Инсталиране"
"инсталиране на преки пътища"
"Разрешава на приложението да добавя преки пътища без намеса на потребителя."
"четене на настройките и преките пътища в Начало"
@@ -59,6 +64,10 @@
"Това е системно приложение и не може да се деинсталира."
"Папка без име"
"Деактивирахте %1$s"
+
+ - %1$s – има %2$d известия
+ - %1$s – има %2$d известие
+
"Страница %1$d от %2$d"
"Начален екран %1$d от %2$d"
"Нова страница на началния екран"
@@ -70,21 +79,21 @@
"Папка: „%1$s“"
"Приспособления"
"Тапети"
- "Настройки за Google Home"
+ "Настройки за началния екран"
"Деактивирано от администратора ви"
- "Общ преглед"
"Разрешаване на завъртането на началния екран"
"При завъртане на телефона"
- "Текущата настройка на екрана не разрешава завъртане"
"Точки за известия"
"Включено"
"Изключено"
"Необходим е достъп до известията"
"За да се показват точки за известия, включете известията за приложението %1$s"
"Промяна на настройките"
+ "Показване на точките за известия"
"Добавяне на икона към началния екран"
"За нови приложения"
"Промяна на формата на иконите"
+ "на началния екран"
"Използване на стандартната системна настройка"
"Квадрат"
"Комбинация от кръг и квадрат"
@@ -99,6 +108,8 @@
"%1$s се изтегля. Завършено: %2$s"
"%1$s изчаква инсталиране"
"Приспособления за %1$s"
+ "Списък с приспособления"
+ "Списъкът с приспособления е затворен"
"Добавяне към началния екран"
"Преместване на елемента тук"
"Елементът е добавен към началния екран"
@@ -114,9 +125,6 @@
"Създаване на папка с елемента „%1$s“"
"Папката е създадена"
"Преместване към началния екран"
- "Преместване на екрана наляво"
- "Преместване на екрана надясно"
- "Екранът е преместен"
"Преоразмеряване"
"Увеличаване на ширината"
"Увеличаване на височината"
@@ -124,8 +132,16 @@
"Намаляване на височината"
"Приспособлението е преоразмерено към ширина %1$s и височина %2$s"
"Преки пътища"
- "%1$d преки пътища за %2$s"
- "%1$d преки пътища и %2$d известия за %3$s"
+ "Преки пътища и известия"
"Отхвърляне"
"Известието е отхвърлено"
+ "Лични"
+ "Служебни"
+ "Служебен потребителски профил"
+ "Тук можете да намерите служебните приложения"
+ "Всяко служебно приложение има значка и организацията ви се грижи за сигурността му. За по-лесен достъп преместете приложенията на началния си екран."
+ "Управлява се от организацията ви"
+ "Известията и приложенията са изключени"
+ "Затваряне"
+ "Затворено"
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
new file mode 100644
index 0000000000..ffeeed76ab
--- /dev/null
+++ b/res/values-bn-rBD/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "কাজ"
+ "অ্যাপ্লিকেশান ইনস্টল করা নেই৷"
+ "অ্যাপ্লিকেশান অনুপলব্ধ"
+ "ডাউনলোড করা অ্যাপ্লিকেশান নিরাপদ মোডে অক্ষম রয়েছে"
+ "সুরক্ষিত মোডে উইজেট নিষ্ক্রিয় থাকে"
+ "শর্টকাটগুলি অনুপলব্ধ"
+ "হোম স্ক্রিন"
+ "কাস্টম অ্যাকশন"
+ "একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"
+ "কোনো উইজেট বেছে নিতে দুবার-আলতো চেপে ধরে থাকুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন৷"
+ "%1$d × %2$d"
+ "%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"
+ "নিজে যোগ করতে টাচ করে ধরে রাখুন"
+ "স্বয়ংক্রিয়ভাবে যোগ করুন"
+ "অ্যাপ খুঁজুন"
+ "অ্যাপ লোড হচ্ছে…"
+ "\"%1$s\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"
+ "আরও অ্যাপ্লিকেশানের জন্য খুঁজুন"
+ "বিজ্ঞপ্তি"
+ "কোনও শর্টকাট বেছে নিতে টাচ করে ধরে থাকুন।"
+ "কোনও শর্টকাট বেছে নিতে ডবল ট্যাপ করে ধরে থাকুন অথবা কাস্টম অ্যাকশন ব্যবহার করুন।"
+ "এই হোম স্ক্রীনে আর কোনো জায়গা নেই৷"
+ "পছন্দসই ট্রে-তে আর কোনো জায়গা নেই"
+ "অ্যাপ্লিকেশানগুলির তালিকা"
+ "ব্যক্তিগত অ্যাপের তালিকা"
+ "কাজের অ্যাপের তালিকা"
+ "হোম"
+ "সরান"
+ "আনইনস্টল করুন"
+ "অ্যাপের তথ্য"
+ "ইনস্টল করুন"
+ "শর্টকাটগুলি ইনস্টল করে"
+ "একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"
+ "হোম সেটিংস এবং শর্টকাটগুলি পড়ে"
+ "হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পড়তে দেয়৷"
+ "হোম সেটিংস এবং শর্টকাটগুলি লেখে"
+ "হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পরিবর্তন করতে দেয়৷"
+ "ফোন কলগুলি করার জন্য %1$s এর অনুমতি নেই"
+ "উইজেট লোড হতে সমস্যা হয়েছে"
+ "সেটআপ"
+ "এটি একটি সিস্টেম অ্যাপ্লিকেশান এবং আনইনস্টল করা যাবে না৷"
+ "নামবিহীন ফোল্ডার"
+ "%1$s অক্ষম করা হয়েছে"
+
+ - %1$s এ %2$dটি বিজ্ঞপ্তি আছে
+ - %1$s এ %2$dটি বিজ্ঞপ্তি আছে
+
+ "%2$dটির মধ্যে %1$dটি পৃষ্ঠা"
+ "%2$dটির %1$d নম্বর হোম স্ক্রিন"
+ "নতুন হোম স্ক্রীনের পৃষ্ঠা"
+ "ফোল্ডার খোলা হয়েছে, %1$d বাই %2$d"
+ "ফোল্ডার বন্ধ করতে আলতো চাপ দিন"
+ "পুনঃনামকরণ সংরক্ষণ করতে আলতো চাপ দিন"
+ "ফোল্ডার বন্ধ করা হয়েছে"
+ "ফোল্ডারের নাম পাল্টে %1$s করা হয়েছে"
+ "ফোল্ডার: %1$s"
+ "উইজেট"
+ "ওয়ালপেপারগুলি"
+ "হোম সেটিংস"
+ "আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"
+ "হোমস্ক্রীন ঘোরানোর অনুমতি দিন"
+ "যখন ফোনটি ঘোরানো হয়"
+ "বিজ্ঞপ্তি ডট"
+ "চালু হয়েছে"
+ "বন্ধ আছে"
+ "বিজ্ঞপ্তিতে অ্যাক্সেস প্রয়োজন"
+ "বিজ্ঞপ্তির ডটগুলি দেখানোর জন্য, %1$s এর অ্যাপ বিজ্ঞপ্তি চালু করুন"
+ "সেটিংস পরিবর্তন করুন"
+ "বিজ্ঞপ্তির ডট দেখুন"
+ "হোম স্ক্রিনে আইকন যোগ করুন"
+ "নতুন অ্যাপ্লিকেশানগুলির জন্যে"
+ "আইকনের আকৃতি পরিবর্তন করুন"
+ "হোম স্ক্রিনে"
+ "সিস্টেমের ডিফল্ট মান ব্যবহার করুন"
+ "চৌকো"
+ "চৌকো-গোলাকার"
+ "গোলাকার"
+ "চোখের জল"
+ "আইকনের আকৃতি পরিবর্তন করা হচ্ছে"
+ "অজানা"
+ "সরান"
+ "অনুসন্ধান"
+ "এই অ্যাপ্লিকেশানটি ইন্সটল করা নাই"
+ "এই আইকনের অ্যাপ্লিকেশানটি ইন্সটল করা নাই। আপনি এটি সরাতে পারেন বা অ্যাপ্লিকেশানটি অনুসন্ধান করে এটি নিজে ইন্সটল করতে পারেন।"
+ "%1$s ডাউনলোড হচ্ছে %2$s সম্পন্ন হয়েছে"
+ "%1$s ইনস্টলের অপেক্ষায় রয়েছে"
+ "%1$s উইজেট"
+ "হোম স্ক্রীনে যোগ করুন"
+ "এখানে আইটেম সরান"
+ "হোম স্ক্রীনে আইটেম যোগ করা হয়েছে"
+ "আইটেম সরানো হয়েছে"
+ "আইটেম সরান"
+ "সারি %1$s কলাম %2$s এ সরান"
+ "অবস্থানে সরান %1$s"
+ "পছন্দসই অবস্থানে সরান %1$s"
+ "আইটেম সরানো হয়েছে"
+ "ফোল্ডারে যোগ করুন: %1$s"
+ "%1$s সহ ফোল্ডারে যোগ করা হয়েছে"
+ "আইটেম ফোল্ডারে যোগ করা হয়েছে"
+ "এর সাথে ফোল্ডার তৈরি করুন: %1$s"
+ "ফোল্ডার তৈরি করা হয়েছে"
+ "হোম স্ক্রীনে সরান"
+ "আবার আকার দিন"
+ "প্রস্থ বাড়ান"
+ "উচ্চতা বাড়ান"
+ "প্রস্থ কমান"
+ "উচ্চতা কমান"
+ "উইজেটের আকার প্রস্থ %1$s উচ্চতা %2$s তে পরিবর্তন করা হয়েছে"
+ "শর্টকাট"
+ "%2$s এর %1$dটি শর্টকার্ট"
+ "%3$s এর জন্য %1$dটি শর্টকাট এবং %2$dটি বিজ্ঞপ্তি"
+ "খারিজ করুন"
+ "বিজ্ঞপ্তি খারিজ করা হয়েছে"
+ "ব্যক্তিগত"
+ "অফিস"
+ "অফিসের প্রোফাইল"
+ "এখানে কাজের অ্যাপ্সগুলি খুঁজুন"
+ "প্রতিটি কাজের অ্যাপে একটি করে ব্যাজ রয়েছে এবং অ্যাপগুলি আপনার প্রতিষ্ঠানের দ্বারা সুরক্ষিত। সহজে অ্যাক্সেস করার জন্য অ্যাপগুলি হোম স্ক্রিনে রাখুন।"
+ "আপনার প্রতিষ্ঠানের দ্বারা পরিচালিত"
+ "বিজ্ঞপ্তি এবং অ্যাপ বন্ধ আছে"
+ "বন্ধ করুন"
+ "বন্ধ"
+
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 471602f47d..651f400ef6 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -35,18 +35,23 @@
"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"
"নিজে যোগ করতে টাচ করে ধরে রাখুন"
"স্বয়ংক্রিয়ভাবে যোগ করুন"
- "অ্যাপ অনুসন্ধান করুন"
+ "অ্যাপ খুঁজুন"
"অ্যাপ লোড হচ্ছে…"
"\"%1$s\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"
- "আরো অ্যাপ্লিকেশানের জন্য অনুসন্ধান করুন"
+ "আরও অ্যাপ্লিকেশানের জন্য খুঁজুন"
"বিজ্ঞপ্তি"
+ "কোনও শর্টকাট বেছে নিতে টাচ করে ধরে থাকুন।"
+ "কোনও শর্টকাট বেছে নিতে ডবল ট্যাপ করে ধরে থাকুন অথবা কাস্টম অ্যাকশন ব্যবহার করুন।"
"এই হোম স্ক্রীনে আর কোনো জায়গা নেই৷"
"পছন্দসই ট্রে-তে আর কোনো জায়গা নেই"
"অ্যাপ্লিকেশানগুলির তালিকা"
+ "ব্যক্তিগত অ্যাপের তালিকা"
+ "কাজের অ্যাপের তালিকা"
"হোম"
"সরান"
"আনইনস্টল করুন"
- "অ্যাপ্লিকেশানের তথ্য"
+ "অ্যাপের তথ্য"
+ "ইনস্টল করুন"
"শর্টকাটগুলি ইনস্টল করে"
"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"
"হোম সেটিংস এবং শর্টকাটগুলি পড়ে"
@@ -59,6 +64,10 @@
"এটি একটি সিস্টেম অ্যাপ্লিকেশান এবং আনইনস্টল করা যাবে না৷"
"নামবিহীন ফোল্ডার"
"%1$s অক্ষম করা হয়েছে"
+
+ - %1$s এ %2$dটি বিজ্ঞপ্তি আছে
+ - %1$s এ %2$dটি বিজ্ঞপ্তি আছে
+
"%2$dটির মধ্যে %1$dটি পৃষ্ঠা"
"%2$dটির %1$d নম্বর হোম স্ক্রিন"
"নতুন হোম স্ক্রীনের পৃষ্ঠা"
@@ -68,23 +77,23 @@
"ফোল্ডার বন্ধ করা হয়েছে"
"ফোল্ডারের নাম পাল্টে %1$s করা হয়েছে"
"ফোল্ডার: %1$s"
- "উইজেটগুলি"
+ "উইজেট"
"ওয়ালপেপারগুলি"
- "হোম এর সেটিংস"
+ "হোম সেটিংস"
"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"
- "এক নজরে"
"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"
"যখন ফোনটি ঘোরানো হয়"
- "বর্তমান প্রদর্শনের সেটিংস ঘোরানোর মঞ্জুরি দেয় না"
"বিজ্ঞপ্তি ডট"
"চালু হয়েছে"
"বন্ধ আছে"
"বিজ্ঞপ্তিতে অ্যাক্সেস প্রয়োজন"
"বিজ্ঞপ্তির ডটগুলি দেখানোর জন্য, %1$s এর অ্যাপ বিজ্ঞপ্তি চালু করুন"
"সেটিংস পরিবর্তন করুন"
+ "বিজ্ঞপ্তির ডট দেখুন"
"হোম স্ক্রিনে আইকন যোগ করুন"
"নতুন অ্যাপ্লিকেশানগুলির জন্যে"
"আইকনের আকৃতি পরিবর্তন করুন"
+ "হোম স্ক্রিনে"
"সিস্টেমের ডিফল্ট মান ব্যবহার করুন"
"চৌকো"
"চৌকো-গোলাকার"
@@ -99,6 +108,10 @@
"%1$s ডাউনলোড হচ্ছে %2$s সম্পন্ন হয়েছে"
"%1$s ইনস্টলের অপেক্ষায় রয়েছে"
"%1$s উইজেট"
+
+
+
+
"হোম স্ক্রীনে যোগ করুন"
"এখানে আইটেম সরান"
"হোম স্ক্রীনে আইটেম যোগ করা হয়েছে"
@@ -114,9 +127,6 @@
"এর সাথে ফোল্ডার তৈরি করুন: %1$s"
"ফোল্ডার তৈরি করা হয়েছে"
"হোম স্ক্রীনে সরান"
- "স্ক্রীন বাঁ দিকে সরান"
- "স্ক্রীন ডান দিকে সরান"
- "স্ক্রীন সরানো হয়েছে"
"আবার আকার দিন"
"প্রস্থ বাড়ান"
"উচ্চতা বাড়ান"
@@ -124,8 +134,16 @@
"উচ্চতা কমান"
"উইজেটের আকার প্রস্থ %1$s উচ্চতা %2$s তে পরিবর্তন করা হয়েছে"
"শর্টকাট"
- "%2$s এর %1$dটি শর্টকার্ট"
- "%3$s এর জন্য %1$dটি শর্টকাট এবং %2$dটি বিজ্ঞপ্তি"
+ "শর্টকাট এবং বিজ্ঞপ্তি"
"খারিজ করুন"
"বিজ্ঞপ্তি খারিজ করা হয়েছে"
+ "ব্যক্তিগত"
+ "অফিস"
+ "অফিসের প্রোফাইল"
+ "এখানে কাজের অ্যাপ্সগুলি খুঁজুন"
+ "প্রতিটি কাজের অ্যাপে একটি করে ব্যাজ রয়েছে এবং অ্যাপগুলি আপনার প্রতিষ্ঠানের দ্বারা সুরক্ষিত। সহজে অ্যাক্সেস করার জন্য অ্যাপগুলি হোম স্ক্রিনে রাখুন।"
+ "আপনার প্রতিষ্ঠানের দ্বারা পরিচালিত"
+ "বিজ্ঞপ্তি এবং অ্যাপ বন্ধ আছে"
+ "বন্ধ করুন"
+ "বন্ধ"
diff --git a/res/values-bs-rBA/strings.xml b/res/values-bs-rBA/strings.xml
new file mode 100644
index 0000000000..40c886603d
--- /dev/null
+++ b/res/values-bs-rBA/strings.xml
@@ -0,0 +1,147 @@
+
+
+
+
+ "Launcher3"
+
+ "Posao"
+ "Aplikacija nije instalirana."
+ "Aplikacija nije dostupna"
+ "Preuzeta aplikacija je onemogućena u sigurnom načinu rada"
+ "Vidžeti su onemogućeni u sigurnom načinu rada."
+ "Prečica nije dostupna"
+ "Početni ekran"
+ "Prilagođene akcije"
+ "Dodirnite & i držite da biste uzeli dodatak."
+ "Dodirnite dvaput & i držite da biste uzeli vidžet ili koristite prilagođene radnje."
+ "%1$d × %2$d"
+ "Širina %1$d, visina %2$d"
+ "Dodirnite i držite da postavite ručno"
+ "Dodaj automatski"
+ "Pretražite aplikacije"
+ "Aplikacije se učitavaju…"
+ "Nije pronađena nijedna aplikacija za upit \"%1$s\""
+ "Pretraži više aplikacija"
+ "Obavještenja"
+ "Dodirnite i držite da uzmete prečicu."
+ "Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."
+ "Na ovom početnom ekranu nema više prostora."
+ "Nema više prostora u ladici Omiljeno"
+ "Spisak aplikacija"
+ "Lista ličnih aplikacija"
+ "Lista poslovnih aplikacija"
+ "Početna"
+ "Ukloni"
+ "Deinstaliraj"
+ "Informacije o aplikaciji"
+ "Instaliraj"
+ "instaliraj prečice"
+ "Dopušta aplikaciji dodavanje prečica bez posredovanja korisnika."
+ "čitaj postavke na početnom ekranu i prečice"
+ "Dopušta aplikaciji čitanje postavki i prečica na početnom ekranu."
+ "zapisuj postavke na početnom ekranu i prečice"
+ "Dopušta aplikaciji promjenu postavki i prečica na početnom ekranu."
+ "%1$s nema odobrenje da uspostavlja telefonske pozive"
+ "Problem pri učitavanju dodatka"
+ "Postavljanje"
+ "Ovo je sistemska aplikacija i ne može se deinstalirati."
+ "Neimenovani folder"
+ "Aplikacija %1$s je onemogućena"
+
+ - %1$s ima %2$d obavještenje
+ - %1$s ima %2$d obavještenja
+ - %1$s ima %2$d obavještenja
+
+ "Strana %1$d od %2$d"
+ "Početni ekran %1$d od %2$d"
+ "Nova stranica početnog ekrana"
+ "Folder je otvoren, (š) %1$d (v) %2$d"
+ "Dodirnite da zatvorite folder"
+ "Dodirnite da sačuvate promjenu naziva"
+ "Folder je zatvoren"
+ "Ime foldera je promijenjeno u %1$s"
+ "Folder: %1$s"
+ "Dodaci"
+ "Pozadinske slike"
+ "Postavke početnog ekrana"
+ "Onemogućio vaš administrator"
+ "Dozvoli rotiranje početnog ekrana"
+ "Kada se telefon zarotira"
+ "Tačke za obavještenja"
+ "Uključeno"
+ "Isključeno"
+ "Potreban je pristup obavještenjima"
+ "Za prikaz tačaka obavještenja, uključite obavještenja za aplikacije za aplikaciju %1$s"
+ "Promijeni postavke"
+ "Prikaži tačke za obavještenja"
+ "Dodaj ikonu na početni ekran"
+ "Za nove aplikacije"
+ "Promjena oblika ikona"
+ "na Početnom ekranu"
+ "Koristite sistemski zadano"
+ "Kvadrat"
+ "Zaobljeni kvadrat"
+ "Krug"
+ "Suza"
+ "Primjenjivanje promjena oblika ikona"
+ "Nepoznato"
+ "Ukloni"
+ "Pretraži"
+ "Ova aplikacija nije instalirana"
+ "Aplikacija za ovu ikonu nije instalirana. Možete je ukloniti ili potražiti aplikaciju i ručno je instalirati."
+ "%1$s se preuzima, završeno %2$s"
+ "%1$s čeka da se instalira"
+ "Vidžeti za aplikaciju %1$s"
+ "Dodaj na početni ekran"
+ "Premjesti stavku ovdje"
+ "Stavka je dodana na Početni ekran."
+ "Stavka je uklonjena"
+ "Premjesti stavku"
+ "Pomjeri stavku u red %1$s kolonu %2$s"
+ "Pomjeri stavku na poziciju %1$s"
+ "Pomjeri stavku na poziciju %1$s među omiljenim"
+ "Stavka je premještena"
+ "Dodaj u folder: %1$s"
+ "Dodaj u folder sa aplikacijom %1$s"
+ "Stavka je dodana u folder"
+ "Kreirajte folder sa stavkom: %1$s"
+ "Folder je kreiran"
+ "Pomjeri na početni ekran"
+ "Promijeni veličinu"
+ "Povećaj širinu"
+ "Povećaj visinu"
+ "Smanji širinu"
+ "Smanji visinu"
+ "Veličina vidžeta je promijenjena na širinu %1$s visinu %2$s"
+ "Prečice"
+ "%1$d prečica za aplikaciju %2$s"
+ "Za aplikaciju %3$s broj prečica je %1$d, a broj obavještenja je %2$d"
+ "Odbaci"
+ "Obavještenje je odbačeno"
+ "Lične"
+ "Poslovne"
+ "Radni profil"
+ "Pronađite poslovne aplikacije ovdje"
+ "Svaka poslovna aplikacija ima značku i osigurava je vaša organizacija. Premjestite aplikacije na Početni ekran, radi lakšeg pristupa."
+ "Upravlja vaša organizacija"
+ "Notifikacije i aplikacije su isključene"
+ "Zatvori"
+ "Zatvoreno"
+
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 49c862a8cd..848176df02 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -30,7 +30,7 @@
"Početni ekran"
"Prilagođene akcije"
"Dodirnite & i držite da biste uzeli dodatak."
- "Dvaput dodirnite & i držite da biste uzeli vidžet ili koristite prilagođene radnje."
+ "Dodirnite dvaput & i držite da biste uzeli vidžet ili koristite prilagođene radnje."
"%1$d × %2$d"
"Širina %1$d, visina %2$d"
"Dodirnite i držite da postavite ručno"
@@ -40,51 +40,61 @@
"Nije pronađena nijedna aplikacija za upit \"%1$s\""
"Pretraži više aplikacija"
"Obavještenja"
+ "Dodirnite i držite da uzmete prečicu."
+ "Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."
"Na ovom početnom ekranu nema više prostora."
- "Nema više prostora u ladici Favoriti"
+ "Nema više prostora u ladici Omiljeno"
"Spisak aplikacija"
+ "Lista ličnih aplikacija"
+ "Lista poslovnih aplikacija"
"Početna"
"Ukloni"
"Deinstaliraj"
"Informacije o aplikaciji"
+ "Instaliraj"
"instaliraj prečice"
"Dopušta aplikaciji dodavanje prečica bez posredovanja korisnika."
"čitaj postavke na početnom ekranu i prečice"
"Dopušta aplikaciji čitanje postavki i prečica na početnom ekranu."
"zapisuj postavke na početnom ekranu i prečice"
"Dopušta aplikaciji promjenu postavki i prečica na početnom ekranu."
- "%1$s nema dozvolu da uspostavlja telefonske pozive"
+ "%1$s nema odobrenje da uspostavlja telefonske pozive"
"Problem pri učitavanju dodatka"
"Postavljanje"
"Ovo je sistemska aplikacija i ne može se deinstalirati."
"Neimenovani folder"
"Aplikacija %1$s je onemogućena"
+
+ - %1$s ima %2$d obavještenje
+ - %1$s ima %2$d obavještenja
+ - %1$s ima %2$d obavještenja
+
"Strana %1$d od %2$d"
"Početni ekran %1$d od %2$d"
"Nova stranica početnog ekrana"
"Folder je otvoren, (š) %1$d (v) %2$d"
"Dodirnite da zatvorite folder"
- "Dodirnite da sačuvate promjenu imena"
+ "Dodirnite da sačuvate promjenu naziva"
"Folder je zatvoren"
"Ime foldera je promijenjeno u %1$s"
"Folder: %1$s"
"Dodaci"
"Pozadinske slike"
- "Postavke za Home"
+ "Postavke početnog ekrana"
"Onemogućio vaš administrator"
- "Pregled"
"Dozvoli rotiranje početnog ekrana"
"Kada se telefon zarotira"
- "Trenutne postavke ekrana ne dozvoljavaju rotiranje"
"Tačke za obavještenja"
"Uključeno"
"Isključeno"
"Potreban je pristup obavještenjima"
"Za prikaz tačaka obavještenja, uključite obavještenja za aplikacije za aplikaciju %1$s"
"Promijeni postavke"
- "Dodajte ikonu na početni ekran"
+ "Prikaži tačke za obavještenja"
+ "Dodaj ikonu na početni ekran"
"Za nove aplikacije"
"Promjena oblika ikona"
+ "na Početnom ekranu"
"Koristite sistemski zadano"
"Kvadrat"
"Zaobljeni kvadrat"
@@ -93,12 +103,14 @@
"Primjenjivanje promjena oblika ikona"
"Nepoznato"
"Ukloni"
- "Traži"
+ "Pretraži"
"Ova aplikacija nije instalirana"
"Aplikacija za ovu ikonu nije instalirana. Možete je ukloniti ili potražiti aplikaciju i ručno je instalirati."
"%1$s se preuzima, završeno %2$s"
"%1$s čeka da se instalira"
"Vidžeti za aplikaciju %1$s"
+ "Spisak vidžeta"
+ "Spisak vidžeta je zatvoren"
"Dodaj na početni ekran"
"Premjesti stavku ovdje"
"Stavka je dodana na Početni ekran."
@@ -106,7 +118,7 @@
"Premjesti stavku"
"Pomjeri stavku u red %1$s kolonu %2$s"
"Pomjeri stavku na poziciju %1$s"
- "Pomjeri stavku na poziciju %1$s među favoritima"
+ "Pomjeri stavku na poziciju %1$s među omiljenim"
"Stavka je premještena"
"Dodaj u folder: %1$s"
"Dodaj u folder sa aplikacijom %1$s"
@@ -114,9 +126,6 @@
"Kreirajte folder sa stavkom: %1$s"
"Folder je kreiran"
"Pomjeri na početni ekran"
- "Pomjeri ekran ulijevo"
- "Pomjeri ekran udesno"
- "Ekran je pomjeren"
"Promijeni veličinu"
"Povećaj širinu"
"Povećaj visinu"
@@ -124,8 +133,16 @@
"Smanji visinu"
"Veličina vidžeta je promijenjena na širinu %1$s visinu %2$s"
"Prečice"
- "%1$d prečica za aplikaciju %2$s"
- "Za aplikaciju %3$s broj prečica je %1$d, a broj obavještenja je %2$d"
+ "Prečice i obavještenja"
"Odbaci"
"Obavještenje je odbačeno"
+ "Lične"
+ "Poslovne"
+ "Radni profil"
+ "Pronađite poslovne aplikacije ovdje"
+ "Svaka poslovna aplikacija ima značku i osigurava je vaša organizacija. Premjestite aplikacije na Početni ekran, radi lakšeg pristupa."
+ "Upravlja vaša organizacija"
+ "Notifikacije i aplikacije su isključene"
+ "Zatvori"
+ "Zatvoreno"
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index b1a1f85e06..27f9c3132a 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -40,13 +40,18 @@
"No s\'ha trobat cap aplicació que coincideixi amb \"%1$s\""
"Cerca més aplicacions"
"Notificacions"
+ "Mantén premuda una drecera per seleccionar-la."
+ "Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades."
"Ja no queda espai en aquesta pantalla d\'inici."
"No hi ha més espai a la safata Preferits."
"Llista d\'aplicacions"
+ "Llista d\'aplicacions personals"
+ "Llista d\'aplicacions per a la feina"
"Inici"
"Suprimeix"
"Desinstal·la"
- "Dades de l\'aplicació"
+ "Informació de l\'aplicació"
+ "Instal·la"
"instal·la dreceres"
"Permet que una aplicació afegeixi dreceres sense la intervenció de l\'usuari."
"llegeix la configuració i les dreceres de la pantalla d\'inici"
@@ -59,6 +64,10 @@
"Aquesta aplicació és una aplicació del sistema i no es pot desinstal·lar."
"Carpeta sense nom"
"S\'ha desactivat %1$s"
+
+ - %1$s té %2$d notificacions
+ - %1$s té %2$d notificació
+
"Pàgina %1$d de %2$d"
"Pantalla d\'inici %1$d de %2$d"
"Pàgina de la pantalla d\'inici nova"
@@ -70,21 +79,21 @@
"Carpeta: %1$s"
"Widgets"
"Fons de pantalla"
- "Configuració de la pantalla d\'inici"
+ "Configuració de pantalla d\'inici"
"Desactivada per l\'administrador"
- "Visió general"
"Permet la rotació de la pantalla d\'inici"
"En girar el telèfon"
- "La configuració actual de la pantalla no permet la rotació"
"Punts de notificació"
"Activat"
"Desactivat"
"Cal que tingui accés a les notificacions"
"Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s"
"Canvia la configuració"
+ "Mostra els punts de notificació"
"Afegeix la icona a la pantalla d\'inici"
"Per a les aplicacions noves"
"Canvia la forma de les icones"
+ "a la pantalla d\'inici"
"Utilitza l\'opció predeterminada del sistema"
"Quadrat"
"Quadrat arrodonit"
@@ -99,6 +108,8 @@
"S\'està baixant %1$s, %2$s completat"
"S\'està esperant per instal·lar %1$s"
"Widgets de: %1$s"
+ "Llista de widgets"
+ "S\'ha tancat la llista de widgets"
"Afegeix a la pantalla d\'inici"
"Mou l\'element aquí"
"S\'ha afegit l\'element a la pantalla d\'inici"
@@ -114,9 +125,6 @@
"Crea una carpeta amb: %1$s"
"Carpeta creada"
"Desplaça a la pantalla d\'inici"
- "Desplaça pantalla a l\'esquerra"
- "Desplaça pantalla a la dreta"
- "S\'ha desplaçat la pantalla"
"Canvia la mida"
"Augmenta l\'amplada"
"Augmenta l\'alçada"
@@ -124,8 +132,16 @@
"Redueix l\'alçada"
"S\'ha canviat la mida del widget a l\'amplada %1$s i l\'alçada %2$s"
"Dreceres"
- "%1$d dreceres per a l\'aplicació %2$s"
- "%1$d dreceres i %2$d notificacions per a %3$s"
+ "Dreceres i notificacions"
"Ignora"
"S\'ha ignorat la notificació"
+ "Personal"
+ "Feina"
+ "Perfil professional"
+ "Cerca aplicacions per a la feina aquí"
+ "Totes les aplicacions per a la feina tenen una insígnia que indica que estan protegides per la teva organització. Mou les aplicacions a la pantalla d\'inici per poder-hi accedir més fàcilment."
+ "Gestionat per la teva organització"
+ "Les notificacions i les aplicacions estan desactivades"
+ "Tanca"
+ "S\'ha tancat"
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index e6dee3c3b3..48adf44be5 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -40,13 +40,18 @@
"Dotazu „%1$s“ neodpovídají žádné aplikace"
"Vyhledat další aplikace"
"Oznámení"
+ "Zkratku vyberete podržením."
+ "Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce."
"Na této ploše již není místo."
"Na panelu Oblíbené položky již není místo."
"Seznam aplikací"
+ "Seznam osobních aplikací"
+ "Seznam pracovních aplikací"
"Plocha"
"Odstranit"
"Odinstalovat"
- "Informace o aplikaci"
+ "O aplikaci"
+ "Nainstalovat"
"instalace zástupce"
"Umožňuje aplikaci přidat zástupce bez zásahu uživatele."
"čtení nastavení a odkazů plochy"
@@ -59,6 +64,12 @@
"Toto je systémová aplikace a nelze ji odinstalovat."
"Složka bez názvu"
"Aplikace %1$s je zakázána"
+
+ - Aplikace %1$s má %2$d oznámení
+ - Aplikace %1$s má %2$d oznámení
+ - Aplikace %1$s má %2$d oznámení
+ - Aplikace %1$s má %2$d oznámení
+
"Strana %1$d z %2$d"
"Plocha %1$d z %2$d"
"Nová stránka plochy"
@@ -72,19 +83,19 @@
"Tapety"
"Nastavení plochy"
"Zakázáno administrátorem"
- "Přehled"
"Povolit otáčení plochy"
"Při otočení telefonu"
- "Aktuální nastavení displeje neumožňuje otáčení"
"Puntíky s oznámením"
"Zapnuto"
"Vypnuto"
"Je třeba udělit přístup k oznámením"
"Chcete-li zobrazovat puntíky s oznámením, zapněte oznámení z aplikace %1$s"
"Změnit nastavení"
+ "Zobrazovat puntíky s oznámením"
"Přidat ikonu na plochu"
"Pro nové aplikace"
"Změnit tvar ikony"
+ "na ploše"
"Použít výchozí nastavení systému"
"Čtverec"
"Kruh/čtverec"
@@ -99,6 +110,8 @@
"Stahování aplikace %1$s (dokončeno %2$s)"
"Instalace aplikace %1$s čeká na zahájení"
"Widgety %1$s"
+ "Seznam widgetů"
+ "Seznam widgetů zavřen"
"Přidat na plochu"
"Přesunout položku sem"
"Položka byla přidána na plochu"
@@ -114,9 +127,6 @@
"Vytvořit složku s položkou %1$s"
"Složka byla vytvořena"
"Přesunout na plochu"
- "Přesunout obrazovku doleva"
- "Přesunout obrazovku doprava"
- "Obrazovka byla přesunuta"
"Změnit velikost"
"Zvýšit šířku"
"Zvýšit výšku"
@@ -124,8 +134,16 @@
"Snížit výšku"
"Velikost widgetu upravena: šířka %1$s, výška %2$s"
"Zkratky"
- "Počet zkratek pro aplikaci %2$s: %1$d"
- "Zkratky (%1$d) a oznámení (%2$d) aplikace %3$s"
+ "Zkratky a oznámení"
"Zavřít"
"Oznámení bylo zavřeno"
+ "Osobní"
+ "Pracovní"
+ "Pracovní profil"
+ "Zde naleznete pracovní aplikace"
+ "Každá pracovní aplikace má odznak a je zabezpečena vaší organizací. Aplikace si můžete pro jednoduchost přesunout na plochu."
+ "Spravováno vaší organizací"
+ "Oznámení a aplikace jsou vypnuty"
+ "Zavřít"
+ "Zavřeno"
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 653105e058..d141ad9ff9 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -40,13 +40,18 @@
"Der blev ikke fundet nogen apps, som matcher \"%1$s\""
"Søg efter flere apps"
"Underretninger"
+ "Hold en genvej nede for at samle den op."
+ "Tryk to gange, og hold en genvej nede for at samle den op eller bruge tilpassede handlinger."
"Der er ikke mere plads på denne startskærm."
"Der er ikke mere plads i bakken Foretrukne"
"Liste med apps"
+ "Liste over personlige apps"
+ "Liste over apps til arbejdet"
"Startskærm"
"Fjern"
"Afinstaller"
- "Oplysninger om appen"
+ "Appinfo"
+ "Installer"
"installere genveje"
"Tillader, at en app tilføjer genveje uden brugerens indgriben."
"læs indstillinger og genveje for startskærmen"
@@ -59,6 +64,10 @@
"Dette er en systemapp, som ikke kan afinstalleres."
"Unavngiven mappe"
"%1$s er deaktiveret"
+
+ - %1$s har %2$d underretning
+ - %1$s har %2$d underretninger
+
"Side %1$d ud af %2$d"
"Startskærm %1$d ud af %2$d"
"Ny startskærm"
@@ -72,19 +81,19 @@
"Baggrunde"
"Indstillinger for startskærmen"
"Deaktiveret af din administrator"
- "Oversigt"
"Tillad rotation af startskærmen"
"Når telefonen roteres"
- "Den aktuelle indstilling for visning tillader ikke rotation"
"Underretningscirkler"
"Til"
"Fra"
"Kræver adgang til underretninger"
"Hvis du vil se underretningscirkler, skal du aktivere appunderretninger for %1$s"
"Skift indstillinger"
+ "Vis underretningscirkler"
"Føj ikon til startskærmen"
"For nye apps"
"Skift ikonform"
+ "på startskærmen"
"Brug systemstandarden"
"Kvadrat"
"Kvadrat med runde hjørner"
@@ -99,6 +108,8 @@
"%1$s downloades. %2$s er gennemført"
"%1$s venter på at installere"
"%1$s-widgets"
+ "Liste med widgets"
+ "Listen med widgets blev lukket"
"Føj til startskærm"
"Flyt elementet hertil"
"Elementet er føjet til startskærmen"
@@ -114,9 +125,6 @@
"Opret mappe med: %1$s"
"Mappen blev oprettet"
"Flyt til startskærmen"
- "Flyt skærmen til venstre"
- "Flyt skærmen til højre"
- "Skærmen er flyttet"
"Tilpas størrelse"
"Øg bredden"
"Øg højden"
@@ -124,8 +132,16 @@
"Reducer højden"
"Størrelsen for widgetten er ændret til bredde %1$s og højde %2$s"
"Genveje"
- "%1$d genveje til %2$s"
- "%1$d genveje og %2$d underretninger for %3$s"
+ "Genveje og underretninger"
"Afvis"
"Underretningen blev afvist"
+ "Personlige"
+ "Arbejde"
+ "Arbejdsprofil"
+ "Find arbejdsapps her"
+ "Alle arbejdsapps har et badge og beskyttes af din organisation. Flyt apps til din startskærm, så du nemmere kan få adgang til dem."
+ "Administreret af din organisation"
+ "Underretninger og apps er slået fra"
+ "Luk"
+ "Lukket"
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1c4cd7a7ca..c309a55689 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -40,13 +40,18 @@
"Keine Apps für \"%1$s\" gefunden"
"Weitere Apps suchen"
"Benachrichtigungen"
+ "Tippen und halten, um eine Verknüpfung auszuwählen."
+ "Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen."
"Auf diesem Startbildschirm ist kein Platz mehr vorhanden."
"Ablage \"Favoriten\" ist voll."
"Liste der Apps"
+ "Liste der privaten Apps"
+ "Liste der geschäftlichen Apps"
"Startseite"
"Entfernen"
"Deinstallieren"
"App-Details"
+ "Installieren"
"Verknüpfungen installieren"
"Ermöglicht einer App das Hinzufügen von Verknüpfungen ohne Eingreifen des Nutzers"
"Einstellungen und Verknüpfungen auf dem Startbildschirm lesen"
@@ -59,6 +64,10 @@
"Dies ist eine Systemanwendung, die nicht deinstalliert werden kann."
"Unbenannter Ordner"
"%1$s deaktiviert"
+
+ - %1$s, hat %2$d Benachrichtigungen
+ - %1$s, hat %2$d Benachrichtigung
+
"Seite %1$d von %2$d"
"Startbildschirm %1$d von %2$d"
"Neue Startbildschirmseite"
@@ -72,19 +81,19 @@
"Hintergründe"
"Einstellungen für den Startbildschirm"
"Von deinem Administrator deaktiviert"
- "Übersicht"
"Drehung des Startbildschirms zulassen"
"Bei Drehung des Smartphones"
- "Die aktuelle \"Display\"-Einstellung verhindert eine Drehung der Anzeige"
"App-Benachrichtigungspunkte"
"Aktiviert"
"Deaktiviert"
"Benachrichtigungszugriff erforderlich"
"Um dir Benachrichtigungspunkte anzeigen zu lassen, aktiviere die Benachrichtigungen für die App \"%1$s\""
"Einstellungen ändern"
+ "App-Benachrichtigungspunkte anzeigen"
"Symbol zu Startbildschirm hinzufügen"
"Für neue Apps"
"Form des Symbols ändern"
+ "auf dem Startbildschirm"
"Systemstandardeinstellung verwenden"
"Quadrat"
"Superkreis"
@@ -99,6 +108,8 @@
"%1$s wird heruntergeladen, %2$s abgeschlossen"
"Warten auf Installation von %1$s"
"%1$s-Widgets"
+ "Widgetliste"
+ "Widgetliste geschlossen"
"Zum Startbildschirm hinzufügen"
"Element hierhin verschieben"
"Element zum Startbildschirm hinzugefügt"
@@ -114,9 +125,6 @@
"Anhand von %1$s Ordner erstellen"
"Ordner erstellt"
"Auf Startbildschirm verschieben"
- "Bildschirm nach links"
- "Bildschirm nach rechts"
- "Bildschirm verschoben"
"Größe anpassen"
"Breite vergrößern"
"Höhe vergrößern"
@@ -124,8 +132,16 @@
"Höhe verringern"
"Größe des Widgets zu Breite %1$s und Höhe %2$s geändert"
"Verknüpfungen"
- "%1$d Verknüpfungen für %2$s"
- "%1$d Verknüpfungen und %2$d Benachrichtigungen für %3$s"
+ "Verknüpfungen und Benachrichtigungen"
"Schließen"
"Benachrichtigung geschlossen"
+ "Privat"
+ "Geschäftlich"
+ "Arbeitsprofil"
+ "Hier findest du Apps für die Arbeit"
+ "Jede App für die Arbeit ist mit einem Logo gekennzeichnet. Deine Organisation kümmert sich um den entsprechenden Schutz. Damit du leichter auf Apps zugreifen kannst, verschiebe sie auf deinen Startbildschirm."
+ "Wird von deiner Organisation verwaltet"
+ "Benachrichtigungen und Apps sind deaktiviert"
+ "Schließen"
+ "Geschlossen"
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 25c8866b85..3208fcbd10 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -40,13 +40,18 @@
"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"%1$s\""
"Αναζήτηση περισσότερων εφαρμογών"
"Ειδοποιήσεις"
+ "Αγγίξτε παρατεταμένα για επιλογή συντόμευσης."
+ "Πατήσετε δύο φορές παρατεταμένα για επιλογή συντόμευσης ή χρήση προσαρμοσμένων ενεργειών."
"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη."
"Δεν υπάρχει επιπλέον χώρος στην περιοχή Αγαπημένα"
"Λίστα εφαρμογών"
+ "Λίστα προσωπικών εφαρμογών"
+ "Λίστα εφαρμογών εργασίας"
"Αρχική οθόνη"
"Κατάργηση"
"Απεγκατάσταση"
"Πληροφορίες εφαρμογής"
+ "Εγκατάσταση"
"εγκατάσταση συντομεύσεων"
"Επιτρέπει σε μια εφαρμογή την προσθήκη συντομεύσεων χωρίς την παρέμβαση του χρήστη."
"ανάγνωση ρυθμίσεων και συντομεύσεων αρχικής οθόνης"
@@ -59,6 +64,10 @@
"Αυτή είναι μια εφαρμογή συστήματος και δεν είναι δυνατή η κατάργηση της εγκατάστασής της."
"Φάκελος χωρίς όνομα"
"Η εφαρμογή %1$s είναι απενεργοποιημένη"
+
+ - Η εφαρμογή %1$s έχει %2$d ειδοποιήσεις
+ - Η εφαρμογή %1$s έχει %2$d ειδοποίηση
+
"Σελίδα %1$d από %2$d"
"Αρχική οθόνη %1$d από %2$d"
"Νέα σελίδα αρχικής οθόνης"
@@ -70,21 +79,21 @@
"Φάκελος: %1$s"
"Γραφικά στοιχεία"
"Ταπετσαρίες"
- "Ρυθμίσεις Αρχικής σελίδας"
+ "Ρυθμίσεις Αρχ. Οθ."
"Απενεργοποιήθηκε από τον διαχειριστή σας"
- "Επισκόπηση"
"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"
"Όταν το τηλέφωνο περιστρέφεται"
- "Η τρέχουσα ρύθμιση οθόνης δεν επιτρέπει την περιστροφή"
"Κουκκίδες ειδοποίησης"
"Ενεργή"
"Ανενεργή"
"Απαιτείται πρόσβαση στις ειδοποιήσεις"
"Για να εμφανιστούν οι Κουκκίδες ειδοποίησης, ενεργοποιήστε τις κουκκίδες εφαρμογής για την εφαρμογή %1$s"
"Αλλαγή ρυθμίσεων"
+ "Εμφάνιση κουκκίδων ειδοποίησης"
"Προσθήκη εικονιδίου στην Αρχική οθόνη"
"Για νέες εφαρμογές"
"Αλλαγή σχήματος εικονιδίου"
+ "στην Αρχική οθόνη"
"Χρήση προεπιλογής συστήματος"
"Τετράγωνο"
"Στρογγυλεμένο τετράγωνο"
@@ -99,6 +108,8 @@
"Λήψη %1$s, ολοκληρώθηκε %2$s"
"%1$s σε αναμονή για εγκατάσταση"
"Γραφικά στοιχεία %1$s"
+ "Λίστα γραφικών στοιχείων"
+ "Η λίστα γραφικών στοιχείων έκλεισε"
"Προσθήκη στην αρχική οθόνη"
"Μετακίνηση στοιχείου εδώ"
"Το στοιχείο προστέθηκε στην αρχική οθόνη"
@@ -114,9 +125,6 @@
"Δημιουργία φακέλου με: %1$s"
"Δημιουργήθηκε φάκελος"
"Μετακίνηση Αρχικής οθόνης"
- "Μετακίνηση οθόνης αριστερά"
- "Μετακίνηση οθόνης δεξιά"
- "Η οθόνη μετακινήθηκε"
"Προσαρμογή μεγέθους"
"Αύξηση του πλάτους"
"Αύξηση του ύψους"
@@ -124,8 +132,16 @@
"Μείωση του ύψους"
"Έγινε προσαρμογή του μεγέθους του γραφικού στοιχείου σε %1$s πλάτος και %2$s ύψος"
"Συντομεύσεις"
- "%1$d συντομεύσεις για %2$s"
- "%1$d συντομεύσεις και %2$d ειδοποιήσεις για την εφαρμογή %3$s"
+ "Συντομεύσεις και ειδοποιήσεις"
"Παράβλεψη"
"Η ειδοποίηση παραβλέφθηκε"
+ "Προσωπικές"
+ "Εργασίας"
+ "Προφίλ εργασίας"
+ "Βρείτε όλες τις εφαρμογές εργασίας εδώ"
+ "Κάθε εφαρμογή εργασίας φέρει ένα σήμα και διατηρείται ασφαλής από τον οργανισμό σας. Μετακινήστε τις εφαρμογές εργασίας στην Αρχική οθόνη, για να έχετε πιο εύκολη πρόσβαση."
+ "Διαχειριζόμενο από τον οργανισμό σας"
+ "Οι ειδοποιήσεις και οι εφαρμογές είναι απενεργοποιημένες"
+ "Κλείσιμο"
+ "Κλειστή"
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index f3f10cc82a..245ee43580 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -40,13 +40,18 @@
"No apps found matching \'%1$s\'"
"Search for more apps"
"Notifications"
+ "Touch & hold to pick up a shortcut."
+ "Double-tap & hold to pick up a shortcut or use custom actions."
"No more room on this Home screen."
"No more room in the Favourites tray"
"Apps list"
+ "Personal apps list"
+ "Work apps list"
"Home"
"Remove"
"Uninstall"
"App info"
+ "Install"
"install shortcuts"
"Allows an app to add shortcuts without user intervention."
"read Home settings and shortcuts"
@@ -59,6 +64,10 @@
"This is a system app and can\'t be uninstalled."
"Unnamed Folder"
"Disabled %1$s"
+
+ - %1$s, has %2$d notifications
+ - %1$s, has %2$d notification
+
"Page %1$d of %2$d"
"Home screen %1$d of %2$d"
"New home screen page"
@@ -72,19 +81,19 @@
"Wallpapers"
"Home settings"
"Disabled by your admin"
- "Overview"
"Allow Homescreen rotation"
"When phone is rotated"
- "Current display setting doesn\'t permit rotation"
"Notification dots"
"On"
"Off"
"Notification access needed"
"To show Notification Dots, turn on app notifications for %1$s"
"Change settings"
+ "Show notification dots"
"Add icon to Home screen"
"For new apps"
"Change icon shape"
+ "on Home screen"
"Use system default"
"Square"
"Squircle"
@@ -99,6 +108,8 @@
"%1$s downloading, %2$s complete"
"%1$s waiting to install"
"%1$s widgets"
+ "Widgets list"
+ "Widgets list closed"
"Add to Home screen"
"Move item here"
"Item added to home screen"
@@ -114,9 +125,6 @@
"Create folder with: %1$s"
"Folder created"
"Move to Home screen"
- "Move screen to left"
- "Move screen to right"
- "Screen moved"
"Re-size"
"Increase width"
"Increase height"
@@ -124,8 +132,16 @@
"Decrease height"
"Widget re-sized to width %1$s height %2$s"
"Short cuts"
- "%1$d shortcuts for %2$s"
- "%1$d shortcuts and %2$d notifications for %3$s"
+ "Shortcuts and notifications"
"Dismiss"
"Notification dismissed"
+ "Personal"
+ "Work"
+ "Work profile"
+ "Find work apps here"
+ "Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."
+ "Managed by your organisation"
+ "Notifications and apps are off"
+ "Close"
+ "Closed"
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index f3f10cc82a..245ee43580 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -40,13 +40,18 @@
"No apps found matching \'%1$s\'"
"Search for more apps"
"Notifications"
+ "Touch & hold to pick up a shortcut."
+ "Double-tap & hold to pick up a shortcut or use custom actions."
"No more room on this Home screen."
"No more room in the Favourites tray"
"Apps list"
+ "Personal apps list"
+ "Work apps list"
"Home"
"Remove"
"Uninstall"
"App info"
+ "Install"
"install shortcuts"
"Allows an app to add shortcuts without user intervention."
"read Home settings and shortcuts"
@@ -59,6 +64,10 @@
"This is a system app and can\'t be uninstalled."
"Unnamed Folder"
"Disabled %1$s"
+
+ - %1$s, has %2$d notifications
+ - %1$s, has %2$d notification
+
"Page %1$d of %2$d"
"Home screen %1$d of %2$d"
"New home screen page"
@@ -72,19 +81,19 @@
"Wallpapers"
"Home settings"
"Disabled by your admin"
- "Overview"
"Allow Homescreen rotation"
"When phone is rotated"
- "Current display setting doesn\'t permit rotation"
"Notification dots"
"On"
"Off"
"Notification access needed"
"To show Notification Dots, turn on app notifications for %1$s"
"Change settings"
+ "Show notification dots"
"Add icon to Home screen"
"For new apps"
"Change icon shape"
+ "on Home screen"
"Use system default"
"Square"
"Squircle"
@@ -99,6 +108,8 @@
"%1$s downloading, %2$s complete"
"%1$s waiting to install"
"%1$s widgets"
+ "Widgets list"
+ "Widgets list closed"
"Add to Home screen"
"Move item here"
"Item added to home screen"
@@ -114,9 +125,6 @@
"Create folder with: %1$s"
"Folder created"
"Move to Home screen"
- "Move screen to left"
- "Move screen to right"
- "Screen moved"
"Re-size"
"Increase width"
"Increase height"
@@ -124,8 +132,16 @@
"Decrease height"
"Widget re-sized to width %1$s height %2$s"
"Short cuts"
- "%1$d shortcuts for %2$s"
- "%1$d shortcuts and %2$d notifications for %3$s"
+ "Shortcuts and notifications"
"Dismiss"
"Notification dismissed"
+ "Personal"
+ "Work"
+ "Work profile"
+ "Find work apps here"
+ "Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."
+ "Managed by your organisation"
+ "Notifications and apps are off"
+ "Close"
+ "Closed"
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index f3f10cc82a..245ee43580 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -40,13 +40,18 @@
"No apps found matching \'%1$s\'"
"Search for more apps"
"Notifications"
+ "Touch & hold to pick up a shortcut."
+ "Double-tap & hold to pick up a shortcut or use custom actions."
"No more room on this Home screen."
"No more room in the Favourites tray"
"Apps list"
+ "Personal apps list"
+ "Work apps list"
"Home"
"Remove"
"Uninstall"
"App info"
+ "Install"
"install shortcuts"
"Allows an app to add shortcuts without user intervention."
"read Home settings and shortcuts"
@@ -59,6 +64,10 @@
"This is a system app and can\'t be uninstalled."
"Unnamed Folder"
"Disabled %1$s"
+
+ - %1$s, has %2$d notifications
+ - %1$s, has %2$d notification
+
"Page %1$d of %2$d"
"Home screen %1$d of %2$d"
"New home screen page"
@@ -72,19 +81,19 @@
"Wallpapers"
"Home settings"
"Disabled by your admin"
- "Overview"
"Allow Homescreen rotation"
"When phone is rotated"
- "Current display setting doesn\'t permit rotation"
"Notification dots"
"On"
"Off"
"Notification access needed"
"To show Notification Dots, turn on app notifications for %1$s"
"Change settings"
+ "Show notification dots"
"Add icon to Home screen"
"For new apps"
"Change icon shape"
+ "on Home screen"
"Use system default"
"Square"
"Squircle"
@@ -99,6 +108,8 @@
"%1$s downloading, %2$s complete"
"%1$s waiting to install"
"%1$s widgets"
+ "Widgets list"
+ "Widgets list closed"
"Add to Home screen"
"Move item here"
"Item added to home screen"
@@ -114,9 +125,6 @@
"Create folder with: %1$s"
"Folder created"
"Move to Home screen"
- "Move screen to left"
- "Move screen to right"
- "Screen moved"
"Re-size"
"Increase width"
"Increase height"
@@ -124,8 +132,16 @@
"Decrease height"
"Widget re-sized to width %1$s height %2$s"
"Short cuts"
- "%1$d shortcuts for %2$s"
- "%1$d shortcuts and %2$d notifications for %3$s"
+ "Shortcuts and notifications"
"Dismiss"
"Notification dismissed"
+ "Personal"
+ "Work"
+ "Work profile"
+ "Find work apps here"
+ "Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."
+ "Managed by your organisation"
+ "Notifications and apps are off"
+ "Close"
+ "Closed"
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index f60e1862ae..368e4ba633 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -40,13 +40,18 @@
"No hay apps que coincidan con \"%1$s\""
"Buscar más apps"
"Notificaciones"
+ "Mantén presionado para elegir un acceso directo."
+ "Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas."
"No hay más espacio en esta pantalla principal."
"La bandeja de favoritos está llena."
"Lista de apps"
+ "Lista de apps personales"
+ "Lista de apps del trabajo"
"Pantalla principal"
"Quitar"
"Desinstalar"
"Información de app"
+ "Instalar"
"instalar accesos directos"
"Permite que una aplicación agregue accesos directos sin que el usuario intervenga."
"leer configuración y accesos directos de la pantalla principal"
@@ -59,6 +64,10 @@
"Esta es una aplicación del sistema y no se puede desinstalar."
"Carpeta sin nombre"
"Se inhabilitó %1$s"
+
+ - %1$s tiene %2$d notificaciones
+ - %1$s tiene %2$d notificación
+
"Página %1$d de %2$d"
"Pantalla principal %1$d de %2$d"
"Nueva página en la pantalla principal"
@@ -70,22 +79,22 @@
"Carpeta: %1$s"
"Widgets"
"Fondos de pantalla"
- "Configuración de Home"
+ "Configuración de página principal"
"El administrador inhabilitó esta función"
- "Recientes"
"Permitir la rotación de la pantalla principal"
"Al girar el teléfono"
- "La configuración actual no permite la rotación de la pantalla"
"Puntos de notificación"
"Activada"
"Desactivada"
"Se necesita acceso a las notificaciones"
"Para mostrar los puntos de notificación, activa las notificaciones de la app para %1$s"
"Cambiar la configuración"
+ "Mostrar puntos de notificación"
"Agregar ícono a la pantalla principal"
"Para nuevas apps"
"Cambiar forma de los íconos"
- "Usar el sistema predeterminado"
+ "en la pantalla principal"
+ "Usar valores predeterminados del sistema"
"Cuadrado"
"Cuadrado con esquinas redondeadas"
"Círculo"
@@ -99,6 +108,8 @@
"Se completó el %2$s de la descarga de %1$s"
"Instalación de %1$s en espera"
"Widgets de %1$s"
+ "Lista de widgets"
+ "Se cerró la lista de widgets"
"Agregar a la pantalla principal"
"Mover elemento aquí"
"Se agregó el elemento a la pantalla principal."
@@ -114,9 +125,6 @@
"Crear carpeta con: %1$s"
"Carpeta creada"
"Mover a la pantalla principal"
- "Mover pantalla a la izquierda"
- "Mover pantalla a la derecha"
- "Se movió la pantalla."
"Ajustar tamaño"
"Aumentar el ancho"
"Aumentar la altura"
@@ -124,8 +132,16 @@
"Reducir la altura"
"Se cambió la dimensión del widget a %1$s de ancho y %2$s de alto."
"Accesos directos"
- "%1$d accesos directos para %2$s"
- "%1$d accesos directos y %2$d notificaciones de %3$s"
+ "Accesos directos y notificaciones"
"Descartar"
"Se descartó la notificación"
+ "Personales"
+ "Laborales"
+ "Perfil de trabajo"
+ "Apps de trabajo"
+ "Cada app de trabajo tiene una insignia y está protegida por tu organización. Transfiere las apps a la pantalla principal para acceder a ellas con mayor facilidad."
+ "Administrado por tu organización"
+ "Las notificaciones y las apps están desactivadas"
+ "Cerrar"
+ "Cerrado"
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 3ab41caf69..0829533282 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -40,13 +40,18 @@
"No se han encontrado aplicaciones que contengan \"%1$s\""
"Buscar más aplicaciones"
"Notificaciones"
+ "Mantén pulsado para elegir un acceso directo."
+ "Toca dos veces y mantén pulsado para elegir un acceso directo o utilizar acciones personalizadas."
"No queda espacio en la pantalla de inicio."
"La bandeja de favoritos está completa"
"Lista de aplicaciones"
+ "Lista de aplicaciones personales"
+ "Lista de aplicaciones del trabajo"
"Inicio"
"Quitar"
"Desinstalar"
- "Datos de aplicación"
+ "Información de la aplicación"
+ "Instalar"
"instalar accesos directos"
"Permite que una aplicación añada accesos directos sin intervención del usuario."
"leer información de accesos directos y de ajustes de la pantalla de inicio"
@@ -59,6 +64,10 @@
"Esta aplicación es del sistema y no se puede desinstalar."
"Carpeta sin nombre"
"Se ha inhabilitado %1$s"
+
+ - %1$s tiene %2$d notificaciones
+ - %1$s tiene %2$d notificación
+
"Página %1$d de %2$d"
"Pantalla de inicio %1$d de %2$d"
"Nueva página de pantalla de inicio"
@@ -70,21 +79,21 @@
"Carpeta: %1$s"
"Widgets"
"Fondos de pantalla"
- "Ajustes de Home"
+ "Ajustes de la pantalla de inicio"
"Inhabilitada por el administrador"
- "Visión general"
"Permitir rotación de la pantalla de inicio"
"Al girar el teléfono"
- "La configuración de pantalla actual no permite girar la pantalla"
- "Puntos de notificación"
- "Activada"
- "Desactivada"
+ "Burbujas de notificación"
+ "Activado"
+ "Desactivado"
"Se necesita acceso a las notificaciones"
"Para mostrar burbujas de notificación, activa las notificaciones de %1$s"
"Cambiar ajustes"
+ "Mostrar burbujas de notificación"
"Añadir icono a la pantalla de inicio"
- "Para nuevas aplicaciones"
+ "Para aplicaciones nuevas"
"Cambiar forma de los iconos"
+ "en la pantalla de inicio"
"Usar opción predeterminada del sistema"
"Cuadrado"
"Cuadrado con esquinas redondeadas"
@@ -99,6 +108,8 @@
"Descargando %1$s (%2$s completado)"
"Esperando para instalar %1$s"
"Widgets de %1$s"
+ "Lista de widgets"
+ "Lista de widgets cerrada"
"Añadir a la pantalla de inicio"
"Mover elemento aquí"
"Elemento añadido a la pantalla de inicio"
@@ -114,9 +125,6 @@
"Crear carpeta con: %1$s"
"Carpeta creada"
"Mover a la pantalla de inicio"
- "Mover pantalla a la izquierda"
- "Mover pantalla a la derecha"
- "Pantalla movida"
"Modificar tamaño"
"Aumentar ancho"
"Aumentar altura"
@@ -124,8 +132,16 @@
"Reducir altura"
"Se ha modificado el tamaño del widget a %1$s de ancho y %2$s de alto"
"Accesos directos"
- "%1$d accesos directos de %2$s"
- "%1$d accesos directos y %2$d notificaciones de %3$s"
+ "Accesos directos y notificaciones"
"Ignorar"
"Notificación ignorada"
+ "Personal"
+ "Trabajo"
+ "Perfil de trabajo"
+ "Aplicaciones de trabajo"
+ "Cada aplicación de trabajo tiene una insignia y está protegida por tu organización. Mueve las aplicaciones a la pantalla de inicio para acceder a ellas más fácilmente."
+ "Administrada por tu organización"
+ "Las notificaciones y las aplicaciones están desactivadas"
+ "Cerrar"
+ "Cerrada"
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000000..1bde8aac13
--- /dev/null
+++ b/res/values-et-rEE/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Töö"
+ "Rakendus pole installitud."
+ "Rakendus ei ole saadaval"
+ "Allalaetud rakendus on turvarežiimis keelatud"
+ "Turvarežiimis on vidinad keelatud"
+ "Otsetee pole saadaval"
+ "Avaekraan"
+ "Kohandatud toimingud"
+ "Vidina valimiseks vajutage ja hoidke seda all."
+ "Topeltpuudutage ja hoidke vidina valimiseks või kohandatud toimingute kasutamiseks."
+ "%1$d × %2$d"
+ "%1$d lai ja %2$d kõrge"
+ "Puudutage pikalt, et käsitsi asetada"
+ "Lisa automaatselt"
+ "Otsige rakendusi"
+ "Rakenduste laadimine …"
+ "Päringule „%1$s” ei vastanud ükski rakendus"
+ "Otsi rohkem rakendusi"
+ "Märguanded"
+ "Otsetee valimiseks puudutage seda pikalt."
+ "Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."
+ "Sellel avaekraanil pole enam ruumi."
+ "Salves Lemmikud pole rohkem ruumi"
+ "Rakenduste loend"
+ "Isiklike rakenduste loend"
+ "Töörakenduste loend"
+ "Avaekraan"
+ "Eemalda"
+ "Desinstalli"
+ "Rakenduse teave"
+ "Installimine"
+ "installi otseteed"
+ "Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."
+ "loe avaekraani seadeid ja otseteid"
+ "Võimaldab rakendusel lugeda avaekraanil seadeid ja otseteid."
+ "kirjuta avaekraani seaded ja otseteed"
+ "Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid."
+ "Rakendusel %1$s pole lubatud helistada"
+ "Probleem vidina laadimisel"
+ "Seadistamine"
+ "See on süsteemirakendus ja seda ei saa desinstallida."
+ "Nimetu kaust"
+ "Rakendus %1$s on keelatud"
+
+ - %1$s, %2$d märguannet
+ - %1$s – %2$d märguanne
+
+ "Leht %1$d/%2$d"
+ "Avaekraan %1$d/%2$d"
+ "Uus avaekraan"
+ "Kaust on avatud, %1$d x %2$d"
+ "Puudutage kausta sulgemiseks"
+ "Puudutage ümbernimetamise salvestamiseks"
+ "Kaust on suletud"
+ "Kausta uus nimi: %1$s"
+ "Kaust: %1$s"
+ "Vidinad"
+ "Taustapildid"
+ "Avaekraani seaded"
+ "Keelas administraator"
+ "Luba avaekraani pööramine"
+ "Kui telefoni pööratakse"
+ "Märguandetäpid"
+ "Sees"
+ "Väljas"
+ "Vaja on juurdepääsu märguannetele"
+ "Märguandetäppide kuvamiseks lülitage sisse rakenduse %1$s märguanded"
+ "Seadete muutmine"
+ "Kuva märguandetäpid"
+ "Lisa ikoon avaekraanile"
+ "Uute rakenduste puhul"
+ "Ikooni kuju muutmine"
+ "avaekraanil"
+ "Kasuta süsteemi vaikeseadet"
+ "Ruut"
+ "Ümarate nurkadega ruut"
+ "Ring"
+ "Tilk"
+ "Ikooni kuju muudatuste rakendamine"
+ "Teadmata"
+ "Eemalda"
+ "Otsing"
+ "See rakendus ei ole installitud"
+ "Selle ikooni rakendust pole installitud. Saate selle eemaldada või rakendust otsida ja käsitsi installida."
+ "Rakenduse %1$s allalaadimine, %2$s on valmis"
+ "%1$s on installimise ootel"
+ "Teenuse %1$s vidinad"
+ "Lisa avaekraanile"
+ "Teisalda üksus siia"
+ "Üksus lisati avaekraanile"
+ "Üksus eemaldati"
+ "Teisalda üksus"
+ "Teisaldamine %1$s. rea %2$s. veergu"
+ "Teisaldamine %1$s. positsioonile"
+ "Teisaldamine lemmikute %1$s. positsioonile"
+ "Üksus teisaldati"
+ "Lisamine kausta: %1$s"
+ "Lisamine kausta nimega %1$s"
+ "Üksus lisati kausta"
+ "Kausta loomine nimega %1$s"
+ "Kaust on loodud"
+ "Teisalda avaekraanile"
+ "Muuda suurust"
+ "Suurenda laiust"
+ "Suurenda kõrgust"
+ "Vähenda laiust"
+ "Vähenda kõrgust"
+ "Vidina suurust muudeti. Laius: %1$s. Kõrgus: %2$s"
+ "Otseteed"
+ "%1$d otseteed rakenduse %2$s jaoks"
+ "%1$d otseteed ja %2$d märguannet rakendusele %3$s"
+ "Loobu"
+ "Märguandest loobuti"
+ "Isiklik"
+ "Töö"
+ "Tööprofiil"
+ "Töörakendused leiate siit"
+ "Igal töörakendusel on märk ja teie organisatsioon tagab selle turvalisuse. Teisaldage rakendused avaekraanile, et neile oleks lihtsam juurde pääseda."
+ "Haldab teie organisatsioon"
+ "Märguanded ja rakendused on välja lülitatud"
+ "Sule"
+ "Suletud"
+
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 9d9991ddce..1e5caa6427 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -40,13 +40,18 @@
"Päringule „%1$s” ei vastanud ükski rakendus"
"Otsi rohkem rakendusi"
"Märguanded"
+ "Otsetee valimiseks puudutage seda pikalt."
+ "Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."
"Sellel avaekraanil pole enam ruumi."
"Salves Lemmikud pole rohkem ruumi"
"Rakenduste loend"
+ "Isiklike rakenduste loend"
+ "Töörakenduste loend"
"Avaekraan"
"Eemalda"
"Desinstalli"
"Rakenduse teave"
+ "Installimine"
"installi otseteed"
"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."
"loe avaekraani seadeid ja otseteid"
@@ -59,6 +64,10 @@
"See on süsteemirakendus ja seda ei saa desinstallida."
"Nimetu kaust"
"Rakendus %1$s on keelatud"
+
+ - %1$s, %2$d märguannet
+ - %1$s – %2$d märguanne
+
"Leht %1$d/%2$d"
"Avaekraan %1$d/%2$d"
"Uus avaekraan"
@@ -70,21 +79,21 @@
"Kaust: %1$s"
"Vidinad"
"Taustapildid"
- "Avalehe seaded"
+ "Avaekraani seaded"
"Keelas administraator"
- "Ülevaade"
"Luba avaekraani pööramine"
"Kui telefoni pööratakse"
- "Praegune kuvaseade ei luba pööramist"
"Märguandetäpid"
"Sees"
"Väljas"
"Vaja on juurdepääsu märguannetele"
"Märguandetäppide kuvamiseks lülitage sisse rakenduse %1$s märguanded"
"Seadete muutmine"
+ "Kuva märguandetäpid"
"Lisa ikoon avaekraanile"
"Uute rakenduste puhul"
"Ikooni kuju muutmine"
+ "avaekraanil"
"Kasuta süsteemi vaikeseadet"
"Ruut"
"Ümarate nurkadega ruut"
@@ -99,6 +108,8 @@
"Rakenduse %1$s allalaadimine, %2$s on valmis"
"%1$s on installimise ootel"
"Teenuse %1$s vidinad"
+ "Vidinate loend"
+ "Vidinate loend on suletud"
"Lisa avaekraanile"
"Teisalda üksus siia"
"Üksus lisati avaekraanile"
@@ -114,9 +125,6 @@
"Kausta loomine nimega %1$s"
"Kaust on loodud"
"Teisalda avaekraanile"
- "Teisalda ekraan vasakule"
- "Teisalda ekraan paremale"
- "Ekraan teisaldati"
"Muuda suurust"
"Suurenda laiust"
"Suurenda kõrgust"
@@ -124,8 +132,16 @@
"Vähenda kõrgust"
"Vidina suurust muudeti. Laius: %1$s. Kõrgus: %2$s"
"Otseteed"
- "%1$d otseteed rakenduse %2$s jaoks"
- "%1$d otseteed ja %2$d märguannet rakendusele %3$s"
+ "Otseteed ja märguanded"
"Loobu"
"Märguandest loobuti"
+ "Isiklik"
+ "Töö"
+ "Tööprofiil"
+ "Töörakendused leiate siit"
+ "Igal töörakendusel on märk ja teie organisatsioon tagab selle turvalisuse. Teisaldage rakendused avaekraanile, et neile oleks lihtsam juurde pääseda."
+ "Haldab teie organisatsioon"
+ "Märguanded ja rakendused on välja lülitatud"
+ "Sule"
+ "Suletud"
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
new file mode 100644
index 0000000000..128c6f42a3
--- /dev/null
+++ b/res/values-eu-rES/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Lana"
+ "Aplikazioa instalatu gabe dago."
+ "Ez dago erabilgarri aplikazioa"
+ "Deskargatutako aplikazioa modu seguruan desgaitu da"
+ "Widgetak desgaitu egin dira modu seguruan"
+ "Lasterbideak ez daude erabilgarri"
+ "Hasierako pantaila"
+ "Ekintza pertsonalizatuak"
+ "Eduki sakatuta widgeta aukeratzeko."
+ "Sakatu birritan eta eduki sakatuta widgeta aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."
+ "%1$d × %2$d"
+ "%1$d zabal eta %2$d luze"
+ "Eduki sakatuta eskuz gehitzeko"
+ "Gehitu automatikoki"
+ "Bilatu aplikazioetan"
+ "Aplikazioak kargatzen…"
+ "Ez da aurkitu \"%1$s\" bilaketaren emaitzarik"
+ "Bilatu aplikazio gehiago"
+ "Jakinarazpenak"
+ "Eduki sakatuta lasterbide bat aukeratzeko."
+ "Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."
+ "Hasierako pantaila honetan ez dago toki gehiago."
+ "Ez dago toki gehiago Gogokoak erretiluan"
+ "Aplikazioen zerrenda"
+ "Aplikazio pertsonalen zerrenda"
+ "Laneko aplikazioen zerrenda"
+ "Hasiera"
+ "Kendu"
+ "Desinstalatu"
+ "Aplikazioaren datuak"
+ "Instalatu"
+ "Instalatu lasterbideak"
+ "Erabiltzaileak ezer egin gabe lasterbideak gehitzea baimentzen die aplikazioei."
+ "Irakurri hasierako ezarpenak eta lasterbideak"
+ "Hasierako pantailako ezarpenak eta lasterbideak irakurtzea baimentzen die aplikazioei."
+ "Idatzi hasierako ezarpenak eta lasterbideak"
+ "Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei."
+ "%1$s aplikazioak ez du telefono-deiak egiteko baimenik"
+ "Arazo bat izan da widgeta kargatzean"
+ "Konfigurazioa"
+ "Sistema-aplikazioa da hau eta ezin da desinstalatu."
+ "Izenik gabeko karpeta"
+ "%1$s desgaituta dago"
+
+ - %2$d jakinarazpen dauzka %1$s aplikazioak
+ - %2$d jakinarazpen dauka %1$s aplikazioak
+
+ "%1$d/%2$d orria"
+ "%1$d/%2$d hasierako pantaila"
+ "Hasierako pantailaren orri berria"
+ "Karpeta ireki da: %1$d x %2$d"
+ "Karpeta ixteko, sakatu hau"
+ "Izen berria gordetzeko, sakatu hau"
+ "Karpeta itxi da"
+ "Karpetari %1$s izena eman zaio"
+ "Karpeta: %1$s"
+ "Widgetak"
+ "Horma-paperak"
+ "Hasierako pantailaren ezarpenak"
+ "Administratzaileak desgaitu du"
+ "Baimendu hasierako pantaila biratzea"
+ "Telefonoa biratzen denean"
+ "Jakinarazpen-biribiltxoak"
+ "Aktibatuta"
+ "Desaktibatuta"
+ "Jakinarazpenetarako sarbidea behar da"
+ "Jakinarazpen-biribiltxoak ikusteko, aktibatu %1$s aplikazioaren jakinarazpenak"
+ "Aldatu ezarpenak"
+ "Erakutsi jakinarazpen-biribiltxoak"
+ "Gehitu ikonoa hasierako pantailan"
+ "Aplikazio berrietan"
+ "Aldatu ikonoaren forma"
+ "Hasierako pantailan"
+ "Erabili sistemaren balio lehenetsiak"
+ "Karratua"
+ "Ertz biribilduko karratua"
+ "Zirkulua"
+ "Malkoa"
+ "Ikonoaren forman egindako aldaketak aplikatzen"
+ "Ezezaguna"
+ "Kendu"
+ "Bilatu"
+ "Aplikazio hau ez dago instalatuta"
+ "Ikono honen aplikazioa ez dago instalatuta. Ikonoa ken dezakezu, edo aplikazioa bilatu eta eskuz instalatu."
+ "%1$s deskargatzen, %2$s osatuta"
+ "%1$s instalatzeko zain"
+ "%1$s widgetak"
+ "Gehitu hasierako pantailan"
+ "Ekarri elementua hona"
+ "Gehitu da elementua hasierako pantailan"
+ "Kendu da elementua"
+ "Mugitu elementua"
+ "Eraman %1$s. errenkadara, %2$s. zutabera"
+ "Eraman %1$s. postura"
+ "Eraman gogokoen %1$s. postura"
+ "Elementua mugitu da"
+ "Gehitu %1$s karpetan"
+ "Gehitu %1$s duen karpetan"
+ "Elementua karpetan gehitu da"
+ "Sortu karpeta %1$s elementuarekin"
+ "Karpeta sortu da"
+ "Eraman hasierako pantailara"
+ "Aldatu tamaina"
+ "Handitu zabalera"
+ "Handitu altuera"
+ "Txikitu zabalera"
+ "Txikitu altuera"
+ "Aldatu da widgetaren tamaina. Zabalera: %1$s. Altuera: %2$s."
+ "Lasterbideak"
+ "%2$s aplikazioaren %1$d lasterbide"
+ "%3$s aplikazioaren %1$d lasterbide eta %2$d jakinarazpen"
+ "Baztertu"
+ "Baztertu egin da jakinarazpena"
+ "Pertsonalak"
+ "Lanekoak"
+ "Laneko profila"
+ "Hemen dituzu laneko aplikazioak"
+ "Laneko aplikazio bakoitzak bereizgarri bat dauka eta erakundeak babesten du. Aplikazioak errazago atzitzeko, eraman itzazu hasierako pantailara."
+ "Erakundeak kudeatzen du"
+ "Jakinarazpenak eta aplikazioak desaktibatuta daude"
+ "Itxi"
+ "Itxita"
+
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index b6082fadab..b69228a294 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -40,13 +40,18 @@
"Ez da aurkitu \"%1$s\" bilaketaren emaitzarik"
"Bilatu aplikazio gehiago"
"Jakinarazpenak"
+ "Eduki sakatuta lasterbide bat aukeratzeko."
+ "Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."
"Hasierako pantaila honetan ez dago toki gehiago."
"Ez dago toki gehiago Gogokoak erretiluan"
"Aplikazioen zerrenda"
+ "Aplikazio pertsonalen zerrenda"
+ "Laneko aplikazioen zerrenda"
"Hasiera"
"Kendu"
"Desinstalatu"
"Aplikazioaren datuak"
+ "Instalatu"
"Instalatu lasterbideak"
"Erabiltzaileak ezer egin gabe lasterbideak gehitzea baimentzen die aplikazioei."
"Irakurri hasierako ezarpenak eta lasterbideak"
@@ -59,6 +64,10 @@
"Sistema-aplikazioa da hau eta ezin da desinstalatu."
"Izenik gabeko karpeta"
"%1$s desgaituta dago"
+
+ - %2$d jakinarazpen dauzka %1$s aplikazioak
+ - %2$d jakinarazpen dauka %1$s aplikazioak
+
"%1$d/%2$d orria"
"%1$d/%2$d hasierako pantaila"
"Hasierako pantailaren orri berria"
@@ -72,19 +81,19 @@
"Horma-paperak"
"Hasierako pantailaren ezarpenak"
"Administratzaileak desgaitu du"
- "Ikuspegi orokorra"
"Baimendu hasierako pantaila biratzea"
"Telefonoa biratzen denean"
- "Uneko pantaila-ezarpenak ez du onartzen ikuspegia biratzea"
- "Jakinarazteko biribiltxoak"
+ "Jakinarazpen-biribiltxoak"
"Aktibatuta"
"Desaktibatuta"
"Jakinarazpenetarako sarbidea behar da"
- "Jakinarazteko biribiltxoak ikusteko, aktibatu %1$s aplikazioaren jakinarazpenak"
+ "Jakinarazpen-biribiltxoak ikusteko, aktibatu %1$s aplikazioaren jakinarazpenak"
"Aldatu ezarpenak"
+ "Erakutsi jakinarazpen-biribiltxoak"
"Gehitu ikonoa hasierako pantailan"
"Aplikazio berrietan"
"Aldatu ikonoaren forma"
+ "Hasierako pantailan"
"Erabili sistemaren balio lehenetsiak"
"Karratua"
"Ertz biribilduko karratua"
@@ -99,6 +108,8 @@
"%1$s deskargatzen, %2$s osatuta"
"%1$s instalatzeko zain"
"%1$s widgetak"
+ "Widget-zerrenda"
+ "Itxi da widget-zerrenda"
"Gehitu hasierako pantailan"
"Ekarri elementua hona"
"Gehitu da elementua hasierako pantailan"
@@ -114,9 +125,6 @@
"Sortu karpeta %1$s elementuarekin"
"Karpeta sortu da"
"Eraman hasierako pantailara"
- "Eraman pantaila ezkerrera"
- "Eraman pantaila eskuinera"
- "Mugitu da pantaila"
"Aldatu tamaina"
"Handitu zabalera"
"Handitu altuera"
@@ -124,8 +132,16 @@
"Txikitu altuera"
"Aldatu da widgetaren tamaina. Zabalera: %1$s. Altuera: %2$s."
"Lasterbideak"
- "%2$s aplikazioaren %1$d lasterbide"
- "%3$s aplikazioaren %1$d lasterbide eta %2$d jakinarazpen"
+ "Lasterbideak eta jakinarazpenak"
"Baztertu"
"Baztertu egin da jakinarazpena"
+ "Pertsonalak"
+ "Lanekoak"
+ "Laneko profila"
+ "Hemen dituzu laneko aplikazioak"
+ "Laneko aplikazio bakoitzak bereizgarri bat dauka eta erakundeak babesten du. Aplikazioak errazago atzitzeko, eraman itzazu hasierako pantailara."
+ "Erakundeak kudeatzen du"
+ "Jakinarazpenak eta aplikazioak desaktibatuta daude"
+ "Itxi"
+ "Itxita"
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 8fe874b321..aa06188f21 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -28,9 +28,9 @@
"ابزارکها در حالت ایمن غیرفعال هستند"
"میانبر دردسترس نیست"
"صفحه اصلی"
- "عملکردهای سفارشی"
+ "کنشهای سفارشی"
"برای انتخاب ابزارک لمس کنید و نگه دارید."
- "برای انتخاب یک ابزارک، دو ضربه سریع بزنید و نگهدارید یا از اقدامات سفارشی استفاده کنید."
+ "برای انتخاب یک ابزارک، دو ضربه سریع بزنید و نگهدارید یا از کنشهای سفارشی استفاده کنید."
"%1$d × %2$d"
"%1$d عرض در %2$d طول"
"برای قرار دادن بهصورت دستی لمس کنید و بکشید"
@@ -40,13 +40,18 @@
"هیچ برنامهای در مطابقت با «%1$s» پیدا نشد"
"جستجوی برنامههای بیشتر"
"اعلانها"
+ "برای انتخاب میانبر، لمس کنید و نگهدارید."
+ "برای انتخاب میانبر، دو ضربه سریع بزنید و نگهدارید یا از کنشهای سفارشی استفاده کنید."
"فضای بیشتری در این صفحه اصلی موجود نیست."
"فضای بیشتری در سینی موارد دلخواه وجود ندارد"
"فهرست برنامهها"
+ "فهرست برنامههای شخصی"
+ "فهرست برنامههای کاری"
"صفحه اصلی"
"برداشتن"
"حذف نصب"
"اطلاعات برنامه"
+ "نصب"
"نصب میانبرها"
"به برنامه اجازه میدهد میانبرها را بدون دخالت کاربر اضافه کند."
"خواندن تنظیمات و میانبرهای صفحه اصلی"
@@ -59,6 +64,10 @@
"این برنامه سیستمی است و حذف نصب نمیشود."
"پوشه بینام"
"%1$s غیرفعال شد"
+
+ - %1$s %2$d اعلان دارد
+ - %1$s %2$d اعلان دارد
+
"صفحه %1$d از %2$d"
"صفحه اصلی %1$d از %2$d"
"صفحه اصلی جدید"
@@ -72,19 +81,19 @@
"کاغذدیواریها"
"تنظیمات صفحه اصلی"
"توسط سرپرست سیستم غیرفعال شده است"
- "نمای کلی"
"امکان دادن به چرخش صفحه اصلی"
"وقتی تلفن چرخانده میشود"
- "تنظیم نمایشگر کنونی اجازه چرخش نمیدهد"
"نقطههای اعلان"
"روشن"
"خاموش"
"دسترسی به اعلان نیاز است"
"برای نمایش «نقطههای اعلان»، اعلانهای برنامه را برای %1$s روشن کنید"
"تغییر تنظیمات"
+ "نمایش نقطههای اعلان"
"افزودن نماد به صفحه اصلی"
"برای برنامههای جدید"
"تغییر شکل نماد"
+ "در صفحه اصلی"
"استفاده از پیشفرض سیستم"
"مربع"
"مربع با گوشههای گرد"
@@ -99,6 +108,8 @@
"درحال بارگیری %1$s، %2$s کامل شد"
"%1$s درانتظار نصب"
"ابزارکهای %1$s"
+ "فهرست ابزارکها"
+ "فهرست ابزارکها بسته شد"
"افزودن به صفحه اصلی"
"انتقال مورد به اینجا"
"مورد به صفحه اصلی اضافه شد"
@@ -114,9 +125,6 @@
"ایجاد پوشه با: %1$s"
"پوشه ایجاد شد"
"انتقال به صفحه اصلی"
- "انتقال صفحه به چپ"
- "انتقال صفحه به راست"
- "صفحه منتقل شد"
"تغییر اندازه"
"افزایش عرض"
"افزایش ارتفاع"
@@ -124,8 +132,16 @@
"کاهش ارتفاع"
"اندازه ابزارک به عرض %1$s ارتفاع %2$s تغییر کرد"
"میانبرها"
- "%1$d میانبر برای %2$s"
- "%1$d میانبر و %2$d اعلان برای %3$s"
+ "میانبرها و اعلانها"
"رد کردن"
"اعلان رد شد"
+ "شخصی"
+ "محل کار"
+ "نمایه کاری"
+ "اینجا برنامههای کاری را پیدا کنید"
+ "همه برنامههای کاری نشانی دارند و توسط سازمانتان ایمن نگه داشته میشوند. برنامههای کاری را برای دسترسی آسانتر به صفحه اصلی انتقال دهید."
+ "توسط سازمانتان مدیریت میشود"
+ "اعلانها و برنامهها خاموش هستند"
+ "بستن"
+ "بستهشده"
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 016dbbce37..4b361ac3c4 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -33,20 +33,25 @@
"Valitse widget tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla kohdetta pitkään."
"%1$d × %2$d"
"Leveys: %1$d, korkeus: %2$d"
- "Sijoita manuaalisesti koskettamalla pitkään."
+ "Sijoita manuaalisesti koskettamalla pitkään"
"Lisää automaattisesti"
"Hae sovelluksia"
"Ladataan sovelluksia…"
"%1$s ei palauttanut sovelluksia."
"Hae lisää sovelluksia"
"Ilmoitukset"
+ "Valitse pikakuvake painamalla sitä pitkään."
+ "Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään."
"Tässä aloitusruudussa ei ole enää tilaa."
"Suosikit-valikossa ei ole enää tilaa"
"Sovellusluettelo"
+ "Omat sovellukset ‑luettelo"
+ "Työsovellusluettelo"
"Aloitusruutu"
"Poista"
"Poista asennus"
"Sovelluksen tiedot"
+ "Asenna"
"asenna pikakuvakkeita"
"Antaa sovelluksen lisätä pikakuvakkeita itsenäisesti ilman käyttäjän valintaa."
"lue aloitusruudun asetuksia ja pikakuvakkeita"
@@ -59,6 +64,10 @@
"Tämä on järjestelmäsovellus, eikä sitä voi poistaa."
"Nimetön kansio"
"%1$s poistettiin käytöstä"
+
+ - %1$s: %2$d ilmoitusta
+ - %1$s: %2$d ilmoitus
+
"Sivu %1$d / %2$d"
"Aloitusruutu %1$d/%2$d"
"Uusi aloitusnäytön sivu"
@@ -72,19 +81,19 @@
"Taustakuvat"
"Kotiasetukset"
"Järjestelmänvalvoja on poistanut toiminnon käytöstä."
- "Yleiskatsaus"
"Salli aloitusnäytön kiertäminen"
"Kun puhelinta kierretään"
- "Nykyiset näyttöasetukset eivät salli näytön kiertämistä."
"Pistemerkit"
"Käytössä"
"Pois käytöstä"
"Ilmoituksien käyttöoikeus tarvitaan"
"%1$s tarvitsee ilmoitusten käyttöoikeuden, jotta pistemerkkejä voidaan näyttää."
"Muuta asetuksia"
+ "Näytä ilmoituksista kertovat pistemerkit"
"Lisää kuvake aloitusruutuun"
"Uusille sovelluksille"
"Muuta kuvakkeen muotoa"
+ "aloitusnäytöllä"
"Käytä järjestelmän oletusarvoa"
"Neliö"
"Ympyräneliö"
@@ -99,6 +108,8 @@
"%1$s latautuu, valmiina %2$s"
"%1$s odottaa asennusta"
"Widgetit: %1$s"
+ "Widget-luettelo"
+ "Widget-luettelo suljettu"
"Lisää aloitusnäytölle"
"Siirrä kohde tänne"
"Kohde lisättiin aloitusnäytölle."
@@ -114,9 +125,6 @@
"Luo kansio, jossa on %1$s."
"Kansio on luotu."
"Siirrä aloitusnäytölle"
- "Siirrä näyttöä vasemmalle"
- "Siirrä näyttöä oikealle"
- "Näyttö siirrettiin."
"Muuta kokoa"
"Lisää leveyttä"
"Lisää korkeutta"
@@ -124,8 +132,16 @@
"Vähennä korkeutta"
"Widgetin kokoa muutettiin. Sen leveys on nyt %1$s ja korkeus %2$s."
"Pikakuvakkeet"
- "Sovelluksella %2$s on %1$d pikakuvaketta."
- "%3$s: %1$d pikakuvaketta ja %2$d ilmoitusta"
+ "Pikakuvakkeet ja ilmoitukset"
"Hylkää"
"Ilmoitus hylätty"
+ "Henkilökohtaiset"
+ "Työsovellukset"
+ "Työprofiili"
+ "Etsi työsovelluksia tästä"
+ "Kaikki työsovellukset on merkitty, ja organisaatiosi vastaa niiden suojaamisesta. Voit siirtää työsovelluksia aloitusnäytölle käytön helpottamiseksi."
+ "Organisaatiosi hallinnoima"
+ "Ilmoitukset ja sovellukset ovat poissa käytöstä"
+ "Sulje"
+ "Suljettu"
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index e57433d0c3..29b003e081 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -24,7 +24,7 @@
"Travail"
"L\'application n\'est pas installée."
"Application indisponible"
- "L\'application téléchargée est désactivée en mode sécurisé."
+ "L\'application téléchargée est désactivée en mode sans échec."
"Widgets désactivés en mode sans échec"
"Le raccourci n\'est pas disponible"
"Écran d\'accueil"
@@ -40,13 +40,18 @@
"Aucune application trouvée correspondant à « %1$s »"
"Rechercher plus d\'applications"
"Notifications"
+ "Maintenez un doigt sur le raccourci pour l\'ajouter"
+ "Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées."
"Pas d\'espace libre sur l\'écran d\'accueil."
"Il n\'y a plus d\'espace dans la zone des favoris"
"Liste des applications"
+ "Liste des applications personnelles"
+ "Liste des applications professionnelles"
"Accueil"
"Supprimer"
"Désinstaller"
"Détails de l\'appli"
+ "Installer"
"installer des raccourcis"
"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."
"lire les paramètres et les raccourcis de la page d\'accueil"
@@ -59,6 +64,10 @@
"Impossible de désinstaller cette application, car il s\'agit d\'une application système."
"Dossier sans nom"
"L\'application %1$s est désactivée"
+
+ - %1$s a %2$d notification
+ - %1$s a %2$d notifications
+
"Page %1$d sur %2$d"
"Écran d\'accueil %1$d sur %2$d"
"Nouvelle page d\'écran d\'accueil"
@@ -72,19 +81,19 @@
"Fonds d\'écran"
"Paramètres d\'accueil"
"Cette fonction est désactivée par votre administrateur"
- "Présentation"
"Autoriser la rotation de l\'écran d\'accueil"
"Lorsque vous faites pivoter le téléphone"
- "Le mode d\'affichage actuel ne permet pas le pivotement"
"Points de notification"
"Activé"
"Désactivé"
"L\'accès aux notifications est requis"
"Pour afficher les points de notification, activez les notifications d\'application pour %1$s"
"Modifier les paramètres"
+ "Afficher les points de notification"
"Ajouter l\'icône à l\'écran d\'accueil"
"Pour les nouvelles applications"
"Modifier la forme de l\'icône"
+ "sur l\'écran d\'accueil"
"Utiliser les valeurs système par défaut"
"Carré"
"Carré aux coins ronds"
@@ -99,6 +108,8 @@
"Téléchargement de %1$s : %2$s"
"%1$s en attente d\'installation"
"Widgets pour %1$s"
+ "Liste des widgets"
+ "Liste des widgets fermée"
"Ajouter à l\'écran d\'accueil"
"Déplacer l\'élément ici"
"Élément ajouté à l\'écran d\'accueil"
@@ -114,9 +125,6 @@
"Créer un dossier avec : %1$s"
"Dossier créé"
"Déplacer sur l\'écran d\'accueil"
- "Déplacer l\'écran à gauche"
- "Déplacer l\'écran à droite"
- "Écran déplacé"
"Redimensionner"
"Augmenter la largeur"
"Augmenter la hauteur"
@@ -124,8 +132,16 @@
"Diminuer la hauteur"
"Le widget a été redimensionné (largeur : %1$s, hauteur : %2$s)"
"Raccourcis"
- "%1$d raccourcis pour %2$s"
- "%1$d raccourcis et %2$d notifications pour %3$s"
+ "Raccourcis et notifications"
"Ignorer"
"Notification ignorée"
+ "Personnel"
+ "Travail"
+ "Profil professionnel"
+ "Trouvez ici des applications professionnelles"
+ "Chaque application professionnelle comporte un badge, ce qui signifie qu\'elle est sécurisée par votre organisation. Vous pouvez déplacer vos applications vers l\'écran d\'accueil afin d\'y accéder plus facilement."
+ "Géré par votre organisation"
+ "Les notifications et les applications sont désactivées"
+ "Fermer"
+ "Fermé"
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index dde439288c..d47ab427ca 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -40,13 +40,18 @@
"Aucune application ne correspond à la requête \"%1$s\""
"Rechercher plus d\'applications"
"Notifications"
+ "Appui prolongé pour sélectionner un raccourci."
+ "Appuyez 2X et maintenez la pression pour choisir un raccourci ou utilisez les actions personnalisées"
"Pas d\'espace libre sur cet écran d\'accueil."
"Plus d\'espace disponible dans la zone de favoris."
"Liste d\'applications"
+ "Liste des applications personnelles"
+ "Liste des applications professionnelles"
"Accueil"
"Supprimer"
"Désinstaller"
"Infos sur l\'appli"
+ "Installer"
"installer des raccourcis"
"Permettre à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur"
"lire les paramètres et les raccourcis de l\'écran d\'accueil"
@@ -59,6 +64,10 @@
"Impossible de désinstaller cette application, car il s\'agit d\'une application système."
"Dossier sans nom"
"%1$s est désactivé."
+
+ - %1$s comporte %2$d notification
+ - %1$s comporte %2$d notifications
+
"Page %1$d sur %2$d"
"Écran d\'accueil %1$d sur %2$d"
"Nouvelle page d\'écran d\'accueil"
@@ -70,21 +79,21 @@
"Dossier \"%1$s\""
"Widgets"
"Fonds d\'écran"
- "Paramètres de l\'écran d\'accueil"
+ "Paramètres accueil"
"Désactivé par votre administrateur"
- "Vue d\'ensemble"
"Autoriser la rotation de l\'écran d\'accueil"
"Lorsque vous faites pivoter le téléphone"
- "Le paramètre d\'affichage actuel n\'autorise pas la rotation."
"Pastilles de notification"
"Activé"
"Désactivé"
"Accès aux notifications requis"
"Pour afficher les pastilles de notification, activez les notifications de l\'application %1$s"
"Modifier les paramètres"
+ "Afficher les pastilles de notification"
"Ajouter l\'icône à l\'écran d\'accueil"
"Pour les nouvelles applications"
"Modifier la forme des icônes"
+ "sur l\'écran d\'accueil"
"Utiliser la valeur système par défaut"
"Carré"
"Squircle"
@@ -99,6 +108,8 @@
"%1$s en cours de téléchargement, %2$s effectué(s)"
"%1$s en attente d\'installation"
"Widgets %1$s"
+ "Liste des widgets"
+ "La liste des widgets est fermée"
"Ajouter à l\'écran d\'accueil"
"Déplacer l\'élément ici"
"L\'élément a bien été ajouté à l\'écran d\'accueil."
@@ -114,9 +125,6 @@
"Créer un dossier avec \"%1$s\""
"Dossier créé"
"Déplacer vers l\'écran d\'accueil"
- "Déplacer l\'écran vers la gauche"
- "Déplacer l\'écran vers la droite"
- "L\'écran a bien été déplacé."
"Redimensionner"
"Augmenter la largeur"
"Augmenter la hauteur"
@@ -124,8 +132,16 @@
"Diminuer la hauteur"
"Le widget a bien été redimensionné (largeur : %1$s, hauteur : %2$s)."
"Raccourcis"
- "%1$d raccourcis pour %2$s"
- "%1$d raccourcis et %2$d notifications pour %3$s"
+ "Raccourcis et notifications"
"Ignorer"
"Notification ignorée"
+ "Personnelles"
+ "Professionnelles"
+ "Profil professionnel"
+ "Retrouvez ici vos applications professionnelles"
+ "Les applications professionnelles sont accompagnées d\'un badge et sont sécurisées par votre organisation. Vous pouvez les déplacer vers votre écran d\'accueil pour y accéder plus facilement."
+ "Géré par votre organisation"
+ "Les notifications et les applications sont désactivées"
+ "Fermer"
+ "Fermé"
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
new file mode 100644
index 0000000000..1efa5ceadd
--- /dev/null
+++ b/res/values-gl-rES/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Traballo"
+ "A aplicación non está instalada"
+ "A aplicación non está dispoñible"
+ "A aplicación que descargaches está desactivada no modo seguro"
+ "Os widgets están desactivados no modo seguro"
+ "O atallo non está dispoñible"
+ "Pantalla de inicio"
+ "Accións personalizadas"
+ "Mantén premido un widget para seleccionalo."
+ "Toca dúas veces e mantén premido para seleccionar un widget ou utiliza accións personalizadas."
+ "%1$d × %2$d"
+ "%1$d de largo por %2$d de alto"
+ "Mantén premido o elemento para colocalo manualmente"
+ "Engadir automaticamente"
+ "Buscar aplicacións"
+ "Cargando aplicacións…"
+ "Non se atoparon aplicacións que coincidan con \"%1$s\""
+ "Buscar máis aplicacións"
+ "Notificacións"
+ "Mantén premido un atallo para seleccionalo."
+ "Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."
+ "Non hai máis espazo nesta pantalla de inicio."
+ "Non hai máis espazo na bandexa de favoritos"
+ "Lista de aplicacións"
+ "Lista de aplicacións persoais"
+ "Lista de aplicacións de traballo"
+ "Inicio"
+ "Eliminar"
+ "Desinstalar"
+ "Info. da aplicación"
+ "Instalar"
+ "instalar atallos"
+ "Permite a unha aplicación engadir atallos sen intervención do usuario."
+ "ler a configuración e os atallos da pantalla de inicio"
+ "Permite a unha aplicación ler a configuración e os atallos da páxina de inicio."
+ "modificar a configuración e os atallos da pantalla de inicio"
+ "Permite a unha aplicación cambiar a configuración e os atallos da pantalla de inicio."
+ "%1$s non ten permiso para facer chamadas telefónicas"
+ "Produciuse un problema ao cargar o widget"
+ "Configuración"
+ "Esta aplicación é do sistema e non se pode desinstalar."
+ "Cartafol sen nome"
+ "Desactivouse %1$s"
+
+ - %1$s, ten %2$d notificacións
+ - %1$s, ten %2$d notificación
+
+ "Páxina %1$d de %2$d"
+ "Pantalla de inicio %1$d de %2$d"
+ "Nova páxina da pantalla de inicio"
+ "Abriuse o cartafol, %1$d por %2$d"
+ "Toca fóra para pechar o cartafol"
+ "Toca fóra para cambiar o nome do cartafol"
+ "Pechouse o cartafol"
+ "O cartafol cambiou o nome a %1$s"
+ "Cartafol: %1$s"
+ "Widgets"
+ "Fondos de pantalla"
+ "Configuración da pantalla de Inicio"
+ "Función desactivada polo administrador"
+ "Permitir xirar a pantalla de inicio"
+ "Ao xirar o teléfono"
+ "Puntos de notificacións"
+ "Activado"
+ "Desactivado"
+ "Necesítase acceso ás notificacións"
+ "Para que se mostren os puntos de notificacións, activa as notificacións da aplicación %1$s"
+ "Cambiar configuración"
+ "Mostrar puntos de notificación"
+ "Engadir icona á pantalla de inicio"
+ "Para novas aplicacións"
+ "Cambiar forma das iconas"
+ "na pantalla de inicio"
+ "Usar valores predeterminados do sistema"
+ "Cadrado"
+ "Cadrado de bordos redondeados"
+ "Círculo"
+ "Bágoa"
+ "Aplicando cambios na forma das iconas"
+ "Descoñecido"
+ "Eliminar"
+ "Buscar"
+ "Esta aplicación non está instalada"
+ "A aplicación para esta icona non está instalada. Podes eliminala ou buscar a aplicación e instalala manualmente."
+ "Descargando %1$s (%2$s completado)"
+ "Esperando para instalar %1$s"
+ "Widgets de: %1$s"
+ "Engadir á pantalla de inicio"
+ "Mover elemento aquí"
+ "Engadiuse o elemento á pantalla de inicio"
+ "Eliminouse o elemento"
+ "Mover elemento"
+ "Mover á fila %1$s columna %2$s"
+ "Mover á posición %1$s"
+ "Mover á posición dos favoritos %1$s"
+ "Moveuse o elemento"
+ "Engadir ao cartafol: %1$s"
+ "Engadir ao cartafol con %1$s"
+ "Engadiuse o elemento ao cartafol"
+ "Crear cartafol con: %1$s"
+ "Creouse o cartafol"
+ "Mover á pantalla de inicio"
+ "Cambiar tamaño"
+ "Aumentar ancho"
+ "Aumentar altura"
+ "Reducir ancho"
+ "Reducir altura"
+ "Cambiouse o tamaño do widget polo ancho %1$s e a altura %2$s"
+ "Atallos"
+ "%1$d atallos para %2$s"
+ "%1$d atallos e %2$d notificacións para a aplicación %3$s"
+ "Ignorar"
+ "Ignorouse a notificación"
+ "Persoal"
+ "Traballo"
+ "Perfil de traballo"
+ "Buscar aplicacións do traballo aquí"
+ "As aplicacións do traballo teñen unha insignia e están protexidas pola túa organización. Traslada as aplicacións á pantalla de inicio para acceder a elas de forma máis fácil."
+ "Perfil xestionado pola túa organización"
+ "As notificacións e as aplicacións están desactivadas"
+ "Pechar"
+ "Pechada"
+
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index d55514d1e9..b94d693511 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -40,13 +40,18 @@
"Non se atoparon aplicacións que coincidan con \"%1$s\""
"Buscar máis aplicacións"
"Notificacións"
+ "Mantén premido un atallo para seleccionalo."
+ "Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."
"Non hai máis espazo nesta pantalla de inicio."
"Non hai máis espazo na bandexa de favoritos"
"Lista de aplicacións"
+ "Lista de aplicacións persoais"
+ "Lista de aplicacións de traballo"
"Inicio"
"Eliminar"
"Desinstalar"
"Info. da aplicación"
+ "Instalar"
"instalar atallos"
"Permite a unha aplicación engadir atallos sen intervención do usuario."
"ler a configuración e os atallos da pantalla de inicio"
@@ -59,6 +64,10 @@
"Esta aplicación é do sistema e non se pode desinstalar."
"Cartafol sen nome"
"Desactivouse %1$s"
+
+ - %1$s, ten %2$d notificacións
+ - %1$s, ten %2$d notificación
+
"Páxina %1$d de %2$d"
"Pantalla de inicio %1$d de %2$d"
"Nova páxina da pantalla de inicio"
@@ -70,21 +79,21 @@
"Cartafol: %1$s"
"Widgets"
"Fondos de pantalla"
- "Configuración de inicio"
+ "Configuración da pantalla de Inicio"
"Función desactivada polo administrador"
- "Visión xeral"
"Permitir xirar a pantalla de inicio"
"Ao xirar o teléfono"
- "A configuración de visualización actual non permite xirar a pantalla"
"Puntos de notificacións"
"Activado"
"Desactivado"
"Necesítase acceso ás notificacións"
"Para que se mostren os puntos de notificacións, activa as notificacións da aplicación %1$s"
"Cambiar configuración"
+ "Mostrar puntos de notificación"
"Engadir icona á pantalla de inicio"
"Para novas aplicacións"
"Cambiar forma das iconas"
+ "na pantalla de inicio"
"Usar valores predeterminados do sistema"
"Cadrado"
"Cadrado de bordos redondeados"
@@ -99,6 +108,8 @@
"Descargando %1$s (%2$s completado)"
"Esperando para instalar %1$s"
"Widgets de: %1$s"
+ "Lista de widgets"
+ "Pechouse a lista de widgets"
"Engadir á pantalla de inicio"
"Mover elemento aquí"
"Engadiuse o elemento á pantalla de inicio"
@@ -114,9 +125,6 @@
"Crear cartafol con: %1$s"
"Creouse o cartafol"
"Mover á pantalla de inicio"
- "Mover pantalla á esquerda"
- "Mover pantalla á dereita"
- "Moveuse a pantalla"
"Cambiar tamaño"
"Aumentar ancho"
"Aumentar altura"
@@ -124,8 +132,16 @@
"Reducir altura"
"Cambiouse o tamaño do widget polo ancho %1$s e a altura %2$s"
"Atallos"
- "%1$d atallos para %2$s"
- "%1$d atallos e %2$d notificacións para a aplicación %3$s"
+ "Atallos e notificacións"
"Ignorar"
"Ignorouse a notificación"
+ "Persoal"
+ "Traballo"
+ "Perfil de traballo"
+ "Buscar aplicacións do traballo aquí"
+ "As aplicacións do traballo teñen unha insignia e están protexidas pola túa organización. Traslada as aplicacións á pantalla de inicio para acceder a elas de forma máis fácil."
+ "Perfil xestionado pola túa organización"
+ "As notificacións e as aplicacións están desactivadas"
+ "Pechar"
+ "Pechada"
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000000..234fadafcd
--- /dev/null
+++ b/res/values-gu-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "કાર્યાલય"
+ "ઍપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."
+ "ઍપ્લિકેશન ઉપલબ્ધ નથી"
+ "સુરક્ષિત મોડમાં ડાઉનલોડ કરેલ ઍપ્લિકેશન અક્ષમ કરી"
+ "સુરક્ષિત મોડમાં વિજેટ્સ અક્ષમ કર્યા"
+ "શૉર્ટકટ ઉપલબ્ધ નથી"
+ "હોમ સ્ક્રીન"
+ "કસ્ટમ ક્રિયાઓ"
+ "વિજેટ ચૂંટવા માટે સ્પર્શ કરો અને પકડી રાખો."
+ "વિજેટ ચૂંટવા અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટેપ કરો અને પકડી રાખો."
+ "%1$d × %2$d"
+ "%1$d પહોળાઈ X %2$d ઊંચાઈ"
+ "મેન્યુઅલી મૂકવા માટે ટચ કરી દબાવી રાખો"
+ "આપમેળે ઉમેરો"
+ "શોધ ઍપ્લિકેશનો"
+ "ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"
+ "\"%1$s\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"
+ "વધુ ઍપ્લિકેશનો શોધો"
+ "નોટિફિકેશનો"
+ "એક શૉર્ટકટ ચૂંટવા માટે સ્પર્શ કરી રાખો."
+ "એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરીને દબાવી રાખો."
+ "આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી."
+ "મનપસંદ ટ્રે પર વધુ જગ્યા નથી"
+ "ઍપ્લિકેશનોની સૂચિ"
+ "વ્યક્તિગત ઍપની સૂચિ"
+ "કાર્યસ્થળની ઍપની સૂચિ"
+ "હોમ"
+ "દૂર કરો"
+ "અનઇન્સ્ટોલ કરો"
+ "ઍપ્લિકેશન માહિતી"
+ "ઇન્સ્ટૉલ કરો"
+ "શોર્ટકટ્સ ઇન્સ્ટોલ કરો"
+ "એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."
+ "હોમ સેટિંગ્સ અને શોર્ટકટ્સ વાંચો"
+ "એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ વાંચવાની મંજૂરી આપે છે."
+ "હોમ સેટિંગ્સ અને શોર્ટકટ્સ લખો"
+ "એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ બદલવાની મંજૂરી આપે છે."
+ "%1$s ને ફોન કૉલ્સ કરવાની મંજૂરી નથી"
+ "વિજેટ લોડ કરવામાં સમસ્યા"
+ "સેટઅપ"
+ "આ એક સિસ્ટમ ઍપ્લિકેશન છે અને અનઇન્સ્ટોલ કરી શકાતી નથી."
+ "અનામી ફોલ્ડર"
+ "%1$s અક્ષમ કરી"
+
+ - %1$sના %2$d નોટિફિકેશન છે
+ - %1$sના %2$d નોટિફિકેશન છે
+
+ "%2$d માંથી %1$d પૃષ્ઠ"
+ "%2$d માંથી %1$d હોમ સ્ક્રીન"
+ "નવું હોમ સ્ક્રીન પૃષ્ઠ"
+ "%1$d બાય %2$d નું ફોલ્ડર ખોલ્યું"
+ "ફોલ્ડર બંધ કરવા માટે ટૅપ કરો"
+ "નામ બદલવાનું સાચવવા માટે ટૅપ કરો"
+ "ફોલ્ડર બંધ કર્યું"
+ "ફોલ્ડરનું નામ બદલીને %1$s કર્યું"
+ "ફોલ્ડર: %1$s"
+ "વિજેટ્સ"
+ "વૉલપેપર્સ"
+ "હોમ સેટિંગ્સ"
+ "તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"
+ "હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"
+ "જ્યારે ફોન ફેરવવામાં આવે ત્યારે"
+ "સૂચના બિંદુઓ"
+ "ચાલુ"
+ "બંધ"
+ "નોટિફિકેશનનો ઍક્સેસની જરૂરી છે"
+ "નોટિફિકેશન માટેનું ચિહ્ન બતાવવા હેતુ, %1$s માટેની ઍપ્લિકેશન નોટિફિકેશન ચાલુ કરો"
+ "સેટિંગ્સ બદલો"
+ "નોટિફિકેશન માટેનું ચિહ્ન બતાવો"
+ "હોમ સ્ક્રીન પર આઇકન ઉમેરો"
+ "નવી ઍપ્લિકેશનો માટે"
+ "આઇકનનો આકાર બદલો"
+ "હોમ સ્ક્રીન પર"
+ "સિસ્ટમ ડિફૉલ્ટનો ઉપયોગ કરો"
+ "ચોરસ"
+ "ચોરસ જેવું ગોળ"
+ "વર્તુળ"
+ "ટિઅરડ્રોપ"
+ "આઇકનના આકારમાં કરેલ ફેરફારો લાગુ કરી રહ્યા છીએ"
+ "અજાણ્યો"
+ "દૂર કરો"
+ "શોધો"
+ "આ ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"
+ "આ આયકન માટેની ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી. તમે તેને દૂર કરી શકો છો અથવા ઍપ્લિકેશન માટે શોધ કરી અને તેને મેન્યુઅલી ઇન્સ્ટોલ કરી શકો છો."
+ "%1$s ડાઉનલોડ કરી રહ્યાં છે, %2$s પૂર્ણ"
+ "%1$s, ઇન્સ્ટૉલ થવાની રાહ જોઈ રહ્યું છે"
+ "%1$s વિજેટ"
+ "હોમ સ્ક્રીન પર ઉમેરો"
+ "આઇટમ અહીં ખસેડો"
+ "હોમ સ્ક્રીનમાં આઇટમ ઉમેરી"
+ "આઇટમ દૂર કરી"
+ "આઇટમ ખસેડો"
+ "%1$s પંક્તિ %2$s કૉલમ પર ખસેડો"
+ "%1$s સ્થિતિ પર ખસેડો"
+ "મનપસંદ સ્થિતિ %1$s પર ખસેડો"
+ "આઇટમ ખસેડી"
+ "ફોલ્ડરમાં ઉમેરો: %1$s"
+ "%1$s સાથે ફોલ્ડરમાં ઉમેરો"
+ "ફોલ્ડરમાં આઇટમ ઉમેરી"
+ "આની સાથે ફોલ્ડર બનાવો: %1$s"
+ "ફોલ્ડર બનાવ્યું"
+ "હોમ સ્ક્રીન પર ખસેડો"
+ "આકાર બદલો"
+ "પહોળાઈ વધારો"
+ "ઊંચાઈ વધારો"
+ "પહોળાઈ ઘટાડો"
+ "ઊંચાઈ ઘટાડો"
+ "વિજેટનો આકાર બદલીને %1$s પહોળાઈ %2$s ઊંચાઈ કર્યો"
+ "શૉર્ટકટ્સ"
+ "%2$s માટે %1$d શૉર્ટકટ"
+ "%3$s માટે %1$d શૉર્ટકટ અને %2$d સૂચનાઓ"
+ "છોડી દો"
+ "સૂચના છોડી દીધી"
+ "મનગમતી ઍપ"
+ "કાર્યાલયની ઍપ"
+ "કાર્યાલયની પ્રોફાઇલ"
+ "કાર્ય ઍપને અહીંથી મેળવો"
+ "દરેક કાર્ય ઍપ પાસે એક બૅજ હોય છે અને તમારી સંસ્થા દ્વારા તેને સુરક્ષિત રાખવામાં આવે છે. વધુ સરળ ઍક્સેસ માટે ઍપને તમારી હોમ સ્ક્રીન પર ખસેડો."
+ "તમારી સંસ્થા દ્વારા મેનેજ કરેલ"
+ "નોટિફિકેશન અને ઍપ બંધ છે"
+ "બંધ કરો"
+ "બંધ"
+
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 7096a3ee0a..6468d8b753 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -39,14 +39,19 @@
"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"
"\"%1$s\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"
"વધુ ઍપ્લિકેશનો શોધો"
- "સૂચનાઓ"
+ "નોટિફિકેશનો"
+ "એક શૉર્ટકટ ચૂંટવા માટે સ્પર્શ કરી રાખો."
+ "એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરીને દબાવી રાખો."
"આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી."
"મનપસંદ ટ્રે પર વધુ જગ્યા નથી"
"ઍપ્લિકેશનોની સૂચિ"
+ "વ્યક્તિગત ઍપની સૂચિ"
+ "કાર્યસ્થળની ઍપની સૂચિ"
"હોમ"
"દૂર કરો"
"અનઇન્સ્ટોલ કરો"
"ઍપ્લિકેશન માહિતી"
+ "ઇન્સ્ટૉલ કરો"
"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"
"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."
"હોમ સેટિંગ્સ અને શોર્ટકટ્સ વાંચો"
@@ -59,6 +64,10 @@
"આ એક સિસ્ટમ ઍપ્લિકેશન છે અને અનઇન્સ્ટોલ કરી શકાતી નથી."
"અનામી ફોલ્ડર"
"%1$s અક્ષમ કરી"
+
+ - %1$sના %2$d નોટિફિકેશન છે
+ - %1$sના %2$d નોટિફિકેશન છે
+
"%2$d માંથી %1$d પૃષ્ઠ"
"%2$d માંથી %1$d હોમ સ્ક્રીન"
"નવું હોમ સ્ક્રીન પૃષ્ઠ"
@@ -72,19 +81,19 @@
"વૉલપેપર્સ"
"હોમ સેટિંગ્સ"
"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"
- "ઝલક"
"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"
"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"
- "વર્તમાન પ્રદર્શન સેટિંગ ફેરવવાની પરવાનગી આપતી નથી"
"સૂચના બિંદુઓ"
"ચાલુ"
"બંધ"
"નોટિફિકેશનનો ઍક્સેસની જરૂરી છે"
"નોટિફિકેશન માટેનું ચિહ્ન બતાવવા હેતુ, %1$s માટેની ઍપ્લિકેશન નોટિફિકેશન ચાલુ કરો"
"સેટિંગ્સ બદલો"
+ "નોટિફિકેશન માટેનું ચિહ્ન બતાવો"
"હોમ સ્ક્રીન પર આઇકન ઉમેરો"
"નવી ઍપ્લિકેશનો માટે"
"આઇકનનો આકાર બદલો"
+ "હોમ સ્ક્રીન પર"
"સિસ્ટમ ડિફૉલ્ટનો ઉપયોગ કરો"
"ચોરસ"
"ચોરસ જેવું ગોળ"
@@ -99,6 +108,10 @@
"%1$s ડાઉનલોડ કરી રહ્યાં છે, %2$s પૂર્ણ"
"%1$s, ઇન્સ્ટૉલ થવાની રાહ જોઈ રહ્યું છે"
"%1$s વિજેટ"
+
+
+
+
"હોમ સ્ક્રીન પર ઉમેરો"
"આઇટમ અહીં ખસેડો"
"હોમ સ્ક્રીનમાં આઇટમ ઉમેરી"
@@ -114,9 +127,6 @@
"આની સાથે ફોલ્ડર બનાવો: %1$s"
"ફોલ્ડર બનાવ્યું"
"હોમ સ્ક્રીન પર ખસેડો"
- "સ્ક્રીનને ડાબી બાજુ ખસેડો"
- "સ્ક્રીનને જમણી બાજુ ખસેડો"
- "સ્ક્રીન ખસેડી"
"આકાર બદલો"
"પહોળાઈ વધારો"
"ઊંચાઈ વધારો"
@@ -124,8 +134,16 @@
"ઊંચાઈ ઘટાડો"
"વિજેટનો આકાર બદલીને %1$s પહોળાઈ %2$s ઊંચાઈ કર્યો"
"શૉર્ટકટ્સ"
- "%2$s માટે %1$d શૉર્ટકટ"
- "%3$s માટે %1$d શૉર્ટકટ અને %2$d સૂચનાઓ"
+ "શૉર્ટકટ અને નોટિફિકેશનો"
"છોડી દો"
"સૂચના છોડી દીધી"
+ "મનગમતી ઍપ"
+ "કાર્યાલયની ઍપ"
+ "કાર્યાલયની પ્રોફાઇલ"
+ "કાર્ય ઍપને અહીંથી મેળવો"
+ "દરેક કાર્ય ઍપ પાસે એક બૅજ હોય છે અને તમારી સંસ્થા દ્વારા તેને સુરક્ષિત રાખવામાં આવે છે. વધુ સરળ ઍક્સેસ માટે ઍપને તમારી હોમ સ્ક્રીન પર ખસેડો."
+ "તમારી સંસ્થા દ્વારા મેનેજ કરેલ"
+ "નોટિફિકેશન અને ઍપ બંધ છે"
+ "બંધ કરો"
+ "બંધ"
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index f1ee0f2366..1b5ce26794 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -28,40 +28,49 @@
"विजेट सुरक्षित मोड में अक्षम हैं"
"शॉर्टकट उपलब्ध नहीं है"
"होम स्क्रीन"
- "कस्टम कार्रवाई"
- "विजेट को चुनने के लिए स्पर्श करके रखें."
- "कोई विजेट चुनने के लिए डबल टैप करके रखें या कस्टम कार्रवाइयां चुनें."
+ "कस्टम कार्रवाइयां"
+ "विजेट को चुनने के लिए दबाकर रखें"
+ "कोई विजेट चुनने के लिए दो बार छूएं और दबाये रखें या अपने मुताबिक कार्रवाइयां चुनें."
"%1$d × %2$d"
"%1$d चौड़ाई गुणा %2$d ऊंचाई"
- "मैन्युअल रूप से जोड़ने के लिए स्पर्श करके रखें"
+ "खुद जोड़ने के लिए दबाकर रखें"
"अपने आप जोड़ें"
- "ऐप्लिकेशन खोजें"
+ "ऐप सर्च करें"
"ऐप्लिकेशन लोड हो रहे हैं…"
"\"%1$s\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"
- "अधिक ऐप्लिकेशन खोजें"
- "नोटिफ़िकेशन"
- "इस होम स्क्रीन पर स्थान शेष नहीं है."
- "पसंदीदा ट्रे में और स्थान नहीं है"
+ "और ऐप सर्च करें"
+ "सूचनाएं"
+ "शॉर्टकट चुनने के लिए दबाकर रखें."
+ "शॉर्टकट चुनने या पसंद के मुताबिक कार्रवाई करने के लिए दो बार टैप करें और कुछ देर दबाए रखें."
+ "इस होम स्क्रीन पर जगह नहीं बची है"
+ "पसंदीदा ट्रे में और जगह नहीं है"
"ऐप्लिकेशन सूची"
- "होम"
+ "निजी ऐप्लिकेशन की सूची"
+ "काम से जुड़े ऐप्लिकेशन की सूची"
+ "होम पेज"
"निकालें"
"अनइंस्टॉल करें"
"ऐप की जानकारी"
+ "इंस्टॉल करें"
"शॉर्टकट इंस्टॉल करें"
- "ऐप्लिकेशन को उपयोगकर्ता के हस्तक्षेप के बिना शॉर्टकट जोड़ने देती है."
- "होम सेटिंग और शॉर्टकट पढ़ें"
- "ऐप्लिकेशन को होम में सेटिंग और शॉर्टकट पढ़ने देती है."
- "होम सेटिंग और शॉर्टकट लिखें"
- "ऐप्लिकेशन को होम में सेटिंग और शॉर्टकट बदलने देती है."
+ "ऐप को उपयोगकर्ता के हस्तक्षेप के बिना शॉर्टकट जोड़ने देती है."
+ "होम पेज की सेटिंग और शॉर्टकट पढ़ें"
+ "ऐप्लिकेशन को होम पेज में सेटिंग और शॉर्टकट पढ़ने देती है."
+ "होम पेज की सेटिंग और शॉर्टकट लिखें"
+ "ऐप्लिकेशन को होम पेज में सेटिंग और शॉर्टकट बदलने देती है."
"%1$s को फ़ोन कॉल करने की अनुमति नहीं है"
"विजेट लोड करने में समस्या"
"सेटअप"
"यह एक सिस्टम ऐप्लिकेशन है और इसे अनइंस्टॉल नहीं किया जा सकता."
"अनामित फ़ोल्डर"
"%1$s अक्षम है"
+
+ - %1$s की %2$d सूचनाएं हैं
+ - %1$s की %2$d सूचनाएं हैं
+
"पेज %2$d में से %1$d"
"होम स्क्रीन %2$d में से %1$d"
- "नया होम स्क्रीन पृष्ठ"
+ "नया होम स्क्रीन पेज"
"फ़ोल्डर खोला गया, %1$d गुणा %2$d"
"फ़ोल्डर बंद करने के लिए टैप करें"
"नाम बदलना सहेजने के लिए टैप करें"
@@ -70,35 +79,39 @@
"फ़ोल्डर: %1$s"
"शॉर्टकट"
"वॉलपेपर"
- "होम सेटिंग"
- "आपके व्यवस्थापक द्वारा अक्षम"
- "खास जानकारी"
+ "होम पेज की सेटिंग"
+ "आपके एडमिन ने बंद किया हुआ है"
"होमस्क्रीन घुमाने की अनुमति दें"
"फ़ोन घुुमाए जाने पर"
- "वर्तमान प्रदर्शन सेटिंग घुमाने की अनुमति नहीं देती"
- "नोटिफ़िकेशन बिंदु"
+ "सूचना बिंदु"
"चालू"
"बंद"
- "नोटिफ़िकेशन एक्सेस ज़रूरी है"
- "नोटिफ़िकेशन बिंदु दिखाने के लिए, %1$s के ऐप्लिकेशन नोटिफ़िकेशन चालू करें"
+ "सूचना के एक्सेस की ज़रूरत है"
+ "सूचना बिंदु दिखाने के लिए, %1$s के ऐप्लिकेशन सूचना चालू करें"
"सेटिंग बदलें"
- "होम स्क्रीन में आइकन जोड़ें"
+ "नए नोटिफ़िकेशन बताने वाला गोल निशान दिखाएं"
+ "होम स्क्रीन में आइकॉन जोड़ें"
"नए ऐप्लिकेशन के लिए"
- "आइकन का आकार बदलें"
+ "आइकॉन का आकार बदलें"
+ "होम स्क्रीन पर"
"सिस्टम डिफ़ॉल्ट का उपयोग करें"
"वर्ग"
"गोल कोनों वाला वर्ग"
"मंडली"
"आंसू की बूंद"
- "आइकन के आकार में बदलाव लागू किए जा रहे हैं"
+ "आइकॉन के आकार में बदलाव किए जा रहे हैं"
"अज्ञात"
"निकालें"
- "खोजें"
+ "सर्च करें"
"यह ऐप्स इंस्टॉल नहीं है"
- "इस आइकन का ऐप्स इंस्टॉल नहीं है. आप उसे निकाल सकते हैं या ऐप्स की खोज करके उसे मैन्युअल रूप से इंस्टॉल कर सकते हैं."
+ "इस आइकॉन का ऐप इंस्टॉल नहीं है. आप उसे निकाल सकते हैं या ऐप को खोज कर उसे मैन्युअल रूप से इंस्टॉल कर सकते हैं."
"%1$s डाउनलोड हो रहा है, %2$s पूर्ण"
"%1$s के इंस्टॉल होने की प्रतीक्षा की जा रही है"
"%1$s विजेट"
+
+
+
+
"होम स्क्रीन में जोड़ें"
"आइटम यहां ले जाएं"
"होम स्क्रीन में आइटम जोड़ा गया"
@@ -114,9 +127,6 @@
"इसके साथ फ़ोल्डर बनाएं: %1$s"
"फ़ोल्डर बनाया गया"
"होम स्क्रीन पर ले जाएं"
- "स्क्रीन को बाएं ले जाएं"
- "स्क्रीन को दाएं ले जाएं"
- "स्क्रीन ले जाई गई"
"आकार बदलें"
"चौड़ाई बढ़ाएं"
"ऊंचाई बढ़ाएं"
@@ -124,8 +134,16 @@
"ऊंचाई घटाएं"
"विजेट का आकार बदलकर उसकी चौड़ाई %1$s और ऊंचाई %2$s कर दी गई"
"शॉर्टकट"
- "%2$s के लिए %1$d शॉर्टकट"
- "%3$s के लिए %1$d शॉर्टकट और %2$d नोटिफ़िकेशन हैं"
+ "शॉर्टकट और सूचनाएं"
"खारिज करें"
- "नोटिफ़िकेशन को खारिज किया गया"
+ "सूचना को खारिज किया गया"
+ "निजी ऐप"
+ "काम से जुड़े ऐप"
+ "कार्य प्रोफ़ाइल"
+ "काम से जुड़े सभी ऐप्लिकेशन यहां पाएं"
+ "काम से जुड़े हर ऐप्लिकेशन पर एक बैज (निशान) होता है और इन ऐप्लिकेशन की सुरक्षा आपका संगठन करता है. आसानी से इस्तेमाल करने के लिए ऐप्लिकेशन को अपनी होम स्क्रीन पर ले जाएं."
+ "आपका संगठन प्रबंधित कर रहा है"
+ "सूचनाएं और ऐप्लिकेशन बंद हैं"
+ "बंद करें"
+ "बंद कर दिया गया"
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index aaae258b80..ea340d68a7 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -40,13 +40,18 @@
"Nema aplikacija podudarnih s upitom \"%1$s\""
"Traži više aplikacija"
"Obavijesti"
+ "Dodirnite i zadržite kako biste podigli prečac."
+ "Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama."
"Na ovom početnom zaslonu više nema mjesta."
"Nema više prostora na traci Favoriti"
"Popis aplikacija"
+ "Popis osobnih aplikacija"
+ "Popis radnih aplikacija"
"Početna"
"Ukloni"
"Deinstaliraj"
"Info o aplikaciji"
+ "Instaliraj"
"instaliranje prečaca"
"Aplikaciji omogućuje dodavanje prečaca bez intervencije korisnika."
"čitanje postavki početnog zaslona i prečaca"
@@ -59,6 +64,11 @@
"Ovo je aplikacija sustava i ne može se ukloniti."
"Neimenovana mapa"
"Aplikacija %1$s onemogućena"
+
+ - %1$s, ima %2$d obavijest
+ - %1$s, ima %2$d obavijesti
+ - %1$s, ima %2$d obavijesti
+
"Stranica %1$d od %2$d"
"Početni zaslon %1$d od %2$d"
"Nova stranica početnog zaslona"
@@ -70,21 +80,21 @@
"Mapa: %1$s"
"Widgeti"
"Pozadine"
- "Postavke Homea"
+ "Postavke početnog zaslona"
"Onemogućio administrator"
- "Pregled"
"Dopusti zakretanje početnog zaslona"
"Kada se telefon zakrene"
- "Trenutačna postavka zaslona ne dopušta zakretanje"
"Točke obavijesti"
"Uključeno"
"Isključeno"
"Potreban je pristup obavijestima"
"Za prikaz točaka obavijesti uključite obavijesti aplikacije %1$s"
"Promjena postavki"
+ "Prikaži točke obavijesti"
"Dodaj ikonu na početni zaslon"
"Za nove aplikacije"
"Promijeni oblik ikona"
+ "na početnom zaslonu"
"Upotrijebi zadane postavke sustava"
"Kvadrat"
"Zaobljeni kvadrat"
@@ -99,6 +109,8 @@
"Preuzimanje aplikacije %1$s, dovršeno %2$s"
"Čekanje na instaliranje aplikacije %1$s"
"%1$s widgeti"
+ "Popis widgeta"
+ "Popis widgeta zatvoren"
"Dodavanje na početni zaslon"
"Premjesti stavku ovdje"
"Stavka je dodana na početni zaslon"
@@ -114,9 +126,6 @@
"Izrada mape pomoću stavke: %1$s"
"Mapa izrađena"
"Premještanje na početni zaslon"
- "Premještanje zaslona ulijevo"
- "Premještanje zaslona udesno"
- "Zaslon je premješten"
"Promjena veličine"
"Povećanje širine"
"Povećanje visine"
@@ -124,8 +133,16 @@
"Smanjenje visine"
"Širina widgeta promijenjena je na %1$s, a visina na %2$s"
"Prečaci"
- "Prečaca za aplikaciju %2$s: %1$d"
- "Za aplikaciju %3$s ima prečaca (ukupno %1$d) i obavijesti (ukupno %2$d)"
+ "Prečaci i obavijesti"
"Odbaci"
"Obavijest je odbačena"
+ "Osobno"
+ "Posao"
+ "Radni profil"
+ "Ovdje možete pronaći radne aplikacije"
+ "Svaka radna aplikacija ima značku i štiti je vaša organizacija. Premjestite aplikacije na početni zaslon radi lakšeg pristupa."
+ "Pod upravljanjem vaše organizacije"
+ "Obavijesti i aplikacije isključeni su"
+ "Zatvori"
+ "Zatvoreno"
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 2da64b06bc..7b8738186e 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -40,13 +40,18 @@
"Nem található alkalmazás a(z) „%1$s” lekérdezésre"
"További alkalmazások keresése"
"Értesítések"
+ "Felvételhez tartsa nyomva a parancsikont."
+ "Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket."
"Nincs több hely ezen a kezdőképernyőn."
"Nincs több hely a Kedvencek tálcán"
"Alkalmazások listája"
+ "Személyes alkalmazások listája"
+ "Munkahelyi alkalmazások listája"
"Főoldal"
"Törlés"
"Eltávolítás"
"Alkalmazásinformáció"
+ "Telepítés"
"parancsikonok telepítése"
"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül adjon hozzá parancsikonokat."
"Főoldal beállításainak és parancsikonjainak beolvasása"
@@ -59,6 +64,10 @@
"Ez egy rendszeralkalmazás, és nem lehet eltávolítani."
"Névtelen mappa"
"A(z) %1$s letiltva"
+
+ - A(z) %1$s %2$d értesítéssel rendelkezik
+ - A(z) %1$s %2$d értesítéssel rendelkezik
+
"%2$d/%1$d. oldal"
"%2$d/%1$d. kezdőképernyő"
"Új kezdőképernyő oldal"
@@ -70,21 +79,21 @@
"Mappa: %1$s"
"Modulok"
"Háttérképek"
- "A Home beállításai"
+ "Kezdőoldal beállításai"
"A rendszergazda letiltotta"
- "Áttekintés"
"A kezdőképernyő elforgatásának engedélyezése"
"A telefon elforgatásakor"
- "A jelenlegi kijelzőbeállítások nem teszik lehetővé az elforgatást"
"Értesítési pöttyök"
"Bekapcsolva"
"Kikapcsolva"
"Értesítésekhez való hozzáférésre van szükség"
"Az értesítési pöttyök megjelenítéséhez kapcsolja be a(z) %1$s alkalmazás értesítéseit"
"Beállítások módosítása"
+ "Értesítési pöttyök megjelenítése"
"Ikon hozzáadása a kezdőképernyőhöz"
"Új alkalmazásoknál"
"Ikon formájának módosítása"
+ "a kezdőképernyőn"
"Alapértelmezett érték használata"
"Négyzet"
"Squircle"
@@ -99,6 +108,8 @@
"A(z) %1$s letöltése, %2$s kész"
"A(z) %1$s telepítésre vár"
"%1$s-modulok"
+ "Widgetlista"
+ "Widgetlista bezárva"
"Hozzáadás a kezdőképernyőhöz"
"Elem áthelyezése ide"
"Elem hozzáadva a kezdőképernyőhöz"
@@ -114,9 +125,6 @@
"Mappa létrehozása a következővel: %1$s"
"Mappa létrehozva"
"Áthelyezés a kezdőképernyőre"
- "Képernyő mozgatása balra"
- "Képernyő mozgatása jobbra"
- "Képernyő áthelyezve"
"Átméretezés"
"Szélesség növelése"
"Magasság növelése"
@@ -124,8 +132,16 @@
"Magasság csökkentése"
"Modul átméretezve %1$s szélességre és %2$s magasságra"
"Gyorsparancsok"
- "%1$d gyorsparancs a(z) %2$s számára"
- "%1$d parancsikon és %2$d értesítés a következő alkalmazásnál: %3$s"
+ "Parancsikonok és értesítések"
"Elvetés"
"Értesítés elvetve"
+ "Személyes"
+ "Munkahelyi"
+ "Munkaprofil"
+ "Itt kereshet munkahelyi alkalmazásokat"
+ "A munkahelyi alkalmazásoknál jelvény található, és biztonságukról az Ön szervezete gondoskodik. A könnyebb hozzáférés érdekében helyezze át az alkalmazásokat a kezdőképernyőre."
+ "Az Ön szervezete kezeli"
+ "Az értesítések és az alkalmazások ki vannak kapcsolva"
+ "Bezárás"
+ "Bezárva"
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000000..6844a27573
--- /dev/null
+++ b/res/values-hy-rAM/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Աշխատանքային"
+ "Ծրագիրը տեղադրված չէ:"
+ "Հավելվածը հասանելի չէ"
+ "Ներբեռնված ծրագիրն անջատված է Անվտանգ ռեժիմում"
+ "Վիջեթներն անջատված են անվտանգ ռեժիմում"
+ "Դյուրանցումն անհասանելի է"
+ "Հիմնական էկրան"
+ "Հատուկ գործողություններ"
+ "Հպեք և պահեք՝ վիջեթն ընտրելու համար:"
+ "Կրկնակի հպեք և պահեք՝ վիջեթ ավելացնելու համար կամ օգտվեք հարմարեցրած գործողություններից:"
+ "%1$d × %2$d"
+ "Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"
+ "Հպեք և պահեք՝ ձեռքով տեղադրելու համար"
+ "Ավելացնել ավտոմատ կերպով"
+ "Որոնել հավելվածներ"
+ "Հավելվածների բեռնում…"
+ "«%1$s» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"
+ "Որոնել այլ հավելվածներ"
+ "Ծանուցումներ"
+ "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։"
+ "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:"
+ "Այլևս տեղ չկա այս հիմնական էկրանին:"
+ "Ընտրյալների ցուցակում այլևս ազատ տեղ չկա"
+ "Հավելվածների ցանկ"
+ "Անձնական հավելվածների ցանկ"
+ "Աշխատանքային հավելվածների ցանկ"
+ "Հիմնական"
+ "Հեռացնել"
+ "Հեռացնել"
+ "Հավելվածի տվյալներ"
+ "Տեղադրել"
+ "տեղադրել դյուրանցումներ"
+ "Ծրագրին թույլ է տալիս ավելացնել դյուրանցումներ՝ առանց օգտագործողի միջամտության:"
+ "կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները"
+ "Ծրագրին թույլ է տալիս կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները:"
+ "ստեղծել հիմնաէջի կարգավորումներ ու դյուրանցումներ"
+ "Ծրագրին թույլ է տալիս փոփոխել հիմնաէջի կարգավորումներն ու դյուրանցումները:"
+ "%1$s հավելվածին չի թույլատրվում հեռախոսազանգեր կատարել"
+ "Վիջեթի բեռնման խնդիր կա"
+ "Կարգավորում"
+ "Սա համակարգային ծրագիր է և չի կարող ապատեղադրվել:"
+ "Անանուն պանակ"
+ "%1$s հավելվածն անջատված է"
+
+ - %1$s, ունի %2$d ծանուցում
+ - %1$s, ունի %2$d ծանուցում
+
+ "Էջ %1$d՝ %2$d-ից"
+ "Հիմնական էկրան %1$d` %2$d-ից"
+ "Հիմնական էկրանի նոր էջ"
+ "Պանակը բաց է, %1$d-ից %2$d"
+ "Հպեք՝ պանակը փակելու համար"
+ "Հպեք՝ նոր անվանումը պահելու համար"
+ "Պանակը փակ է"
+ "Պանակը վերանվանվեց %1$s"
+ "Պանակ՝ %1$s"
+ "Վիջեթներ"
+ "Պաստառներ"
+ "Գլխավոր էջի կարգավորումներ"
+ "Անջատվել է ձեր ադմինիստրատորի կողմից"
+ "Թույլ տալ հիմնական էկրանի պտտումը"
+ "Հեռախոսը պտտելու դեպքում"
+ "Ծանուցումների կետիկներ"
+ "Միացված է"
+ "Անջատված է"
+ "Անհրաժեշտ է ծանուցման թույլտվություն"
+ "Ծանուցումների կետիկները ցուցադրելու համար միացրեք ծանուցումները %1$s-ի համար"
+ "Փոխել կարգավորումները"
+ "Ցուցադրել ծանուցումների կետիկները"
+ "Ավելացնել պատկերակը Հիմնական էկրանին"
+ "Նոր հավելվածների համար"
+ "Փոխել պատկերակների տեսքը"
+ "հիմնական էկրանին"
+ "Օգտագործել համակարգի կանխադրված կարգավորումը"
+ "Քառակուսի"
+ "Քառանկյուն"
+ "Օղակ"
+ "Արցունքաձև"
+ "Պատկերակների տեսքի փոփոխությունները կիրառվում են"
+ "Անհայտ է"
+ "Հեռացնել"
+ "Գտնել"
+ "Այս ծրագիրը տեղադրված չէ:"
+ "Այս պատկերակի ծրագիրը տեղադրված չէ: Դուք կարող եք հեռացնել այն կամ գտնել ծրագիրը և տեղադրել այն ձեռքով:"
+ "%1$s–ի ներբեռնում (%2$s)"
+ "%1$s-ի տեղադրման սպասում"
+ "%1$s վիջեթներ"
+ "Ավելացնել Հիմնական էկրանին"
+ "Տեղափոխել տարրն այստեղ"
+ "Տարրն ավելացվեց հիմնական էկրանին"
+ "Տարրը հեռացվեց"
+ "Տեղափոխել տարրը"
+ "Տեղափոխել տող %1$s սյունակ %2$s"
+ "Տեղափոխել դիրք %1$s"
+ "Տեղափոխել նախընտրած դիրք՝ %1$s"
+ "Տարրը տեղափոխվեց"
+ "Ավելացնել թղթապանակում՝ %1$s"
+ "Ավելացնել «%1$s» պանակին"
+ "Տարրն ավելացվեց թղթապանակում"
+ "Ստեղծել թղթապանակ, օգտագործելով՝ %1$s"
+ "Պանակը ստեղծվեց"
+ "Տեղափոխել Հիմնական էկրան"
+ "Չափափոխել"
+ "Ավելացնել լայնությունը"
+ "Ավելացնել բարձրությունը"
+ "Նվազեցնել լայնությունը"
+ "Նվազեցնել բարձրությունը"
+ "Վիջեթի լայնությունը փոխվել է %1$s-ի, իսկ բարձրությունը՝ %2$s-ի"
+ "Դյուրանցումներ"
+ "%1$d դյուրանցումներ %2$s հավելվածի համար"
+ "%1$d դյուրացում և %2$d ծանուցում %3$s-ի համար"
+ "Անտեսել"
+ "Ծանուցումը մերժված է"
+ "Անձնական"
+ "Աշխատանքային"
+ "Աշխատանքային պրոֆիլ"
+ "Գտեք աշխատանքային հավելվածներ այստեղ"
+ "Աշխատանքային հավելվածները նշված են հատուկ նշանով: Նման հավելվածների անվտանգությունը ապահովում է ձեր կազմակերպությունը։ Հարմարության համար աշխատանքային հավելվածները կարող եք տեղափոխել հիմնական էկրան։"
+ "Կառավարվում է ձեր կազմակերպության կողմից"
+ "Ծանուցումներն ու հավելվածներն անջատված են"
+ "Փակել"
+ "Փակվեց"
+
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 2b55e966a4..2b4a38bd7b 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -40,13 +40,18 @@
"«%1$s» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"
"Որոնել այլ հավելվածներ"
"Ծանուցումներ"
+ "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։"
+ "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:"
"Այլևս տեղ չկա այս հիմնական էկրանին:"
"Ընտրյալների ցուցակում այլևս ազատ տեղ չկա"
"Հավելվածների ցանկ"
+ "Անձնական հավելվածների ցանկ"
+ "Աշխատանքային հավելվածների ցանկ"
"Հիմնական"
"Հեռացնել"
"Հեռացնել"
"Հավելվածի տվյալներ"
+ "Տեղադրել"
"տեղադրել դյուրանցումներ"
"Ծրագրին թույլ է տալիս ավելացնել դյուրանցումներ՝ առանց օգտագործողի միջամտության:"
"կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները"
@@ -59,6 +64,10 @@
"Սա համակարգային ծրագիր է և չի կարող ապատեղադրվել:"
"Անանուն պանակ"
"%1$s հավելվածն անջատված է"
+
+ - %1$s, ունի %2$d ծանուցում
+ - %1$s, ունի %2$d ծանուցում
+
"Էջ %1$d՝ %2$d-ից"
"Հիմնական էկրան %1$d` %2$d-ից"
"Հիմնական էկրանի նոր էջ"
@@ -72,19 +81,19 @@
"Պաստառներ"
"Գլխավոր էջի կարգավորումներ"
"Անջատվել է ձեր ադմինիստրատորի կողմից"
- "Համատեսք"
"Թույլ տալ հիմնական էկրանի պտտումը"
"Հեռախոսը պտտելու դեպքում"
- "Ցուցադրման ընթացիկ կարգավորումներն արգելում են պտտումը"
- "Ծանուցման կետեր"
+ "Ծանուցումների կետիկներ"
"Միացված է"
"Անջատված է"
"Անհրաժեշտ է ծանուցման թույլտվություն"
- "Ծանուցման կետերը ցուցադրելու համար միացրեք հավելվածի ծանուցումները %1$s-ի համար"
+ "Ծանուցումների կետիկները ցուցադրելու համար միացրեք ծանուցումները %1$s-ի համար"
"Փոխել կարգավորումները"
+ "Ցուցադրել ծանուցումների կետիկները"
"Ավելացնել պատկերակը Հիմնական էկրանին"
"Նոր հավելվածների համար"
"Փոխել պատկերակների տեսքը"
+ "հիմնական էկրանին"
"Օգտագործել համակարգի կանխադրված կարգավորումը"
"Քառակուսի"
"Քառանկյուն"
@@ -99,6 +108,8 @@
"%1$s–ի ներբեռնում (%2$s)"
"%1$s-ի տեղադրման սպասում"
"%1$s վիջեթներ"
+ "Վիջեթների ցանկ"
+ "Վիջեթների ցանկը փակվեց"
"Ավելացնել Հիմնական էկրանին"
"Տեղափոխել տարրն այստեղ"
"Տարրն ավելացվեց հիմնական էկրանին"
@@ -114,9 +125,6 @@
"Ստեղծել թղթապանակ, օգտագործելով՝ %1$s"
"Պանակը ստեղծվեց"
"Տեղափոխել Հիմնական էկրան"
- "Տեղափոխել էկրանը ձախ"
- "Տեղափոխել էկրանը աջ"
- "Էկրանը տեղափոխվեց"
"Չափափոխել"
"Ավելացնել լայնությունը"
"Ավելացնել բարձրությունը"
@@ -124,8 +132,16 @@
"Նվազեցնել բարձրությունը"
"Վիջեթի լայնությունը փոխվել է %1$s-ի, իսկ բարձրությունը՝ %2$s-ի"
"Դյուրանցումներ"
- "%1$d դյուրանցումներ %2$s հավելվածի համար"
- "%1$d դյուրացում և %2$d ծանուցում %3$s-ի համար"
+ "Դյուրանցումներ և ծանուցումներ"
"Անտեսել"
"Ծանուցումը մերժված է"
+ "Անձնական"
+ "Աշխատանքային"
+ "Աշխատանքային պրոֆիլ"
+ "Գտեք աշխատանքային հավելվածներ այստեղ"
+ "Աշխատանքային հավելվածները նշված են հատուկ նշանով: Նման հավելվածների անվտանգությունը ապահովում է ձեր կազմակերպությունը։ Հարմարության համար աշխատանքային հավելվածները կարող եք տեղափոխել հիմնական էկրան։"
+ "Կառավարվում է ձեր կազմակերպության կողմից"
+ "Ծանուցումներն ու հավելվածներն անջատված են"
+ "Փակել"
+ "Փակվեց"
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 379a960d05..78ffc96845 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -30,7 +30,7 @@
"Layar utama"
"Tindakan khusus"
"Sentuh lama untuk memilih widget."
- "Ketuk dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus."
+ "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus."
"%1$d × %2$d"
"lebar %1$d x tinggi %2$d"
"Sentuh & tahan untuk menempatkan secara manual"
@@ -40,13 +40,18 @@
"Tidak ditemukan aplikasi yang cocok dengan \"%1$s\""
"Telusuri aplikasi lainnya"
"Notifikasi"
+ "Tap lama untuk memilih pintasan."
+ "Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus."
"Tidak ada ruang lagi pada layar Utama ini."
"Tidak ada ruang tersisa di baki Favorit"
"Daftar aplikasi"
+ "Daftar aplikasi pribadi"
+ "Daftar aplikasi kantor"
"Layar Utama"
"Hapus"
"Uninstal"
"Info aplikasi"
+ "Instal"
"memasang pintasan"
"Mengizinkan aplikasi menambahkan pintasan tanpa campur tangan pengguna."
"membaca setelan dan pintasan layar Utama"
@@ -59,12 +64,16 @@
"Ini adalah aplikasi sistem dan tidak dapat dicopot pemasangannya."
"Folder Tanpa Nama"
"%1$s dinonaktifkan"
- "Laman %1$d dari %2$d"
+
+ - %1$s, memiliki %2$d notifikasi
+ - %1$s, memiliki %2$d notifikasi
+
+ "Halaman %1$d dari %2$d"
"Layar utama %1$d dari %2$d"
- "Laman layar utama baru"
+ "Halaman layar utama baru"
"Folder dibuka, %1$d x %2$d"
- "Ketuk untuk menutup folder"
- "Ketuk untuk menyimpan ganti nama"
+ "Tap untuk menutup folder"
+ "Tap untuk menyimpan ganti nama"
"Folder ditutup"
"Folder diganti namanya menjadi %1$s"
"Folder: %1$s"
@@ -72,19 +81,19 @@
"Wallpaper"
"Setelan layar Utama"
"Dinonaktifkan oleh admin"
- "Ringkasan"
"Izinkan layar Utama diputar"
"Saat ponsel diputar"
- "Setelan Tampilan Saat Ini tidak memungkinkan putaran"
"Titik notifikasi"
"Aktif"
"Nonaktif"
"Perlu akses notifikasi"
"Guna menampilkan Titik Notifikasi, aktifkan notifikasi aplikasi untuk %1$s"
"Ubah setelan"
- "Tambahkan ikon ke layar Utama"
+ "Tampilkan titik notifikasi"
+ "Tambahkan ikon ke Layar utama"
"Untuk aplikasi baru"
"Ubah bentuk ikon"
+ "di layar Utama"
"Gunakan default sistem"
"Persegi"
"Persegi bundar"
@@ -99,6 +108,8 @@
"%1$s sedang didownload, %2$s selesai"
"%1$s menunggu dipasang"
"Widget %1$s"
+ "Daftar widget"
+ "Daftar widget ditutup"
"Tambahkan ke Layar Utama"
"Pindahkan item ke sini"
"Item ditambahkan ke layar utama"
@@ -114,9 +125,6 @@
"Buat folder dengan: %1$s"
"Folder dibuat"
"Pindahkan ke layar Utama"
- "Pindahkan layar ke kiri"
- "Pindahkan layar ke kanan"
- "Layar dipindahkan"
"Ubah ukuran"
"Tambahi lebar"
"Tambahi tinggi"
@@ -124,8 +132,16 @@
"Kurangi tinggi"
"Widget diubah ukurannya menjadi lebar %1$s tinggi %2$s"
"Pintasan"
- "%1$d pintasan untuk %2$s"
- "%1$d pintasan dan %2$d notifikasi untuk %3$s"
+ "Pintasan dan notifikasi"
"Tutup"
"Notifikasi ditutup"
+ "Pribadi"
+ "Kantor"
+ "Profil kerja"
+ "Temukan aplikasi kerja di sini"
+ "Setiap aplikasi kerja memiliki badge dan dibuat tetap aman oleh organisasi. Pindahkan aplikasi ke Layar utama untuk memudahkan akses."
+ "Dikelola oleh organisasi"
+ "Notifikasi dan aplikasi nonaktif"
+ "Tutup"
+ "Ditutup"
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
new file mode 100644
index 0000000000..3b5dabacce
--- /dev/null
+++ b/res/values-is-rIS/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Vinna"
+ "Forritið er ekki uppsett."
+ "Forritið er ekki í boði"
+ "Sótt forrit er óvirkt í öryggisstillingu"
+ "Græjur eru óvirkar í öruggri stillingu"
+ "Flýtileið er ekki tiltæk"
+ "Heimaskjár"
+ "Sérsniðnar aðgerðir"
+ "Haltu fingri á græju til að grípa hana."
+ "Ýttu tvisvar og haltu fingri á græju til að grípa hana eða notaðu sérsniðnar aðgerðir."
+ "%1$d × %2$d"
+ "%1$d á breidd og %2$d á hæð"
+ "Haltu inni til að staðsetja handvirkt"
+ "Bæta sjálfkrafa við"
+ "Leita í forritum"
+ "Hleður forrit…"
+ "Ekki fundust forrit sem samsvara „%1$s“"
+ "Leita að fleiri forritum"
+ "Tilkynningar"
+ "Haltu fingri á flýtileið til að grípa hana."
+ "Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."
+ "Ekki meira pláss á þessum heimaskjá."
+ "Ekki meira pláss í bakka fyrir uppáhald"
+ "Forritalisti"
+ "Listi yfir eigin forrit"
+ "Listi yfir vinnuforrit"
+ "Heim"
+ "Fjarlægja"
+ "Fjarlægja"
+ "Forritsupplýsingar"
+ "Setja upp"
+ "setja upp flýtileiðir"
+ "Leyfir forriti að bæta við flýtileiðum án íhlutunar notanda."
+ "lesa stillingar og flýtileiðir heimaskjás"
+ "Leyfir forriti að lesa stillingar og flýtileiðir heimaskjás."
+ "skrifa stillingar og flýtileiðir heimaskjás"
+ "Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás."
+ "%1$s hefur ekki leyfi til að hringja símtöl"
+ "Vandamál við að hlaða græju"
+ "Uppsetning"
+ "Þetta er kerfisforrit sem ekki er hægt að fjarlægja."
+ "Ónefnd mappa"
+ "Óvirkt %1$s"
+
+ - %1$s, er með %2$d tilkynningu
+ - %1$s, er með %2$d tilkynningar
+
+ "Síða %1$d af %2$d"
+ "Heimaskjár %1$d af %2$d"
+ "Ný síða á heimaskjá"
+ "Mappa opnuð, %1$d sinnum %2$d"
+ "Ýttu til að loka möppunni"
+ "Ýttu til að vista breytt heiti"
+ "Möppu lokað"
+ "Heiti möppu breytt í %1$s"
+ "Mappa: %1$s"
+ "Græjur"
+ "Veggfóður"
+ "Heimastillingar"
+ "Gert óvirkt af kerfisstjóra"
+ "Leyfa snúning fyrir heimaskjá"
+ "Þegar símanum er snúið"
+ "Tilkynningapunktar"
+ "Kveikt"
+ "Slökkt"
+ "Aðgangs að tilkynningum er krafist"
+ "Til að sýna tilkynningarpunkta skaltu kveikja á forritstilkynningum fyrir %1$s"
+ "Breyta stillingum"
+ "Sýna tilkynningapunkta"
+ "Bæta tákni á heimaskjáinn"
+ "Fyrir ný forrit"
+ "Breyta formi tákns"
+ "á heimaskjá"
+ "Nota sjálfgildi kerfis"
+ "Ferningur"
+ "Ferhringur"
+ "Hringur"
+ "Dropi"
+ "Breytir formi tákns"
+ "Óþekkt"
+ "Fjarlægja"
+ "Leita"
+ "Þetta forrit er ekki uppsett"
+ "Forritið fyrir þetta tákn er ekki uppsett. Þú getur fjarlægt það eða leitað að forritinu og sett það upp handvirkt."
+ "%1$s í niðurhali, %2$s lokið"
+ "%1$s bíður uppsetningar"
+ "%1$s-græjur"
+ "Bæta á heimaskjá"
+ "Færa atriði hingað"
+ "Atriði bætt á heimaskjáinn"
+ "Atriði fjarlægt"
+ "Færa atriði"
+ "Færa í línu %1$s, dálk %2$s"
+ "Færa í stöðu %1$s"
+ "Færa í stöðu %1$s á festisvæði"
+ "Atriði fært"
+ "Setja í möppu: %1$s"
+ "Setja í möppu með %1$s"
+ "Atriði sett í möppu"
+ "Búa til möppu með: %1$s"
+ "Mappa búin til"
+ "Færa á heimaskjá"
+ "Breyta stærð"
+ "Auka breidd"
+ "Auka hæð"
+ "Minnka breidd"
+ "Minnka hæð"
+ "Stærð græju breytt í %1$s á breidd og %2$s á hæð"
+ "Flýtileiðir"
+ "%1$d flýtileiðir fyrir %2$s"
+ "%1$d flýtileiðir og %2$d tilkynningar fyrir %3$s"
+ "Hunsa"
+ "Tilkynningu lokað"
+ "Persónulegt"
+ "Vinna"
+ "Vinnusnið"
+ "Hér finnurðu vinnuforrit"
+ "Öll vinnuforrit eru með merki og fyrirtækið þitt tryggir öryggi þeirra. Færðu forrit yfir á heimaskjáinn til að fá auðveldari aðgang að þeim."
+ "Stjórnað af fyrirtækinu þínu"
+ "Slökkt er á tilkynningum og forritum"
+ "Loka"
+ "Lokað"
+
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index cf178a56ad..04842e4f4b 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -40,13 +40,18 @@
"Ekki fundust forrit sem samsvara „%1$s“"
"Leita að fleiri forritum"
"Tilkynningar"
+ "Haltu fingri á flýtileið til að grípa hana."
+ "Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."
"Ekki meira pláss á þessum heimaskjá."
"Ekki meira pláss í bakka fyrir uppáhald"
"Forritalisti"
+ "Listi yfir eigin forrit"
+ "Listi yfir vinnuforrit"
"Heim"
"Fjarlægja"
"Fjarlægja"
"Forritsupplýsingar"
+ "Setja upp"
"setja upp flýtileiðir"
"Leyfir forriti að bæta við flýtileiðum án íhlutunar notanda."
"lesa stillingar og flýtileiðir heimaskjás"
@@ -59,6 +64,10 @@
"Þetta er kerfisforrit sem ekki er hægt að fjarlægja."
"Ónefnd mappa"
"Óvirkt %1$s"
+
+ - %1$s, er með %2$d tilkynningu
+ - %1$s, er með %2$d tilkynningar
+
"Síða %1$d af %2$d"
"Heimaskjár %1$d af %2$d"
"Ný síða á heimaskjá"
@@ -72,19 +81,19 @@
"Veggfóður"
"Heimastillingar"
"Gert óvirkt af kerfisstjóra"
- "Yfirlit"
"Leyfa snúning fyrir heimaskjá"
"Þegar símanum er snúið"
- "Núverandi skjástilling leyfir ekki snúning"
"Tilkynningapunktar"
"Kveikt"
"Slökkt"
"Aðgangs að tilkynningum er krafist"
"Til að sýna tilkynningarpunkta skaltu kveikja á forritstilkynningum fyrir %1$s"
"Breyta stillingum"
+ "Sýna tilkynningapunkta"
"Bæta tákni á heimaskjáinn"
"Fyrir ný forrit"
"Breyta formi tákns"
+ "á heimaskjá"
"Nota sjálfgildi kerfis"
"Ferningur"
"Ferhringur"
@@ -99,6 +108,8 @@
"%1$s í niðurhali, %2$s lokið"
"%1$s bíður uppsetningar"
"%1$s-græjur"
+ "Græjulisti"
+ "Græjulista lokað"
"Bæta á heimaskjá"
"Færa atriði hingað"
"Atriði bætt á heimaskjáinn"
@@ -114,9 +125,6 @@
"Búa til möppu með: %1$s"
"Mappa búin til"
"Færa á heimaskjá"
- "Færa skjá til vinstri"
- "Færa skjá til hægri"
- "Skjár færður"
"Breyta stærð"
"Auka breidd"
"Auka hæð"
@@ -124,8 +132,16 @@
"Minnka hæð"
"Stærð græju breytt í %1$s á breidd og %2$s á hæð"
"Flýtileiðir"
- "%1$d flýtileiðir fyrir %2$s"
- "%1$d flýtileiðir og %2$d tilkynningar fyrir %3$s"
+ "Flýtileiðir og tilkynningar"
"Hunsa"
"Tilkynningu lokað"
+ "Persónulegt"
+ "Vinna"
+ "Vinnusnið"
+ "Hér finnurðu vinnuforrit"
+ "Öll vinnuforrit eru með merki og fyrirtækið þitt tryggir öryggi þeirra. Færðu forrit yfir á heimaskjáinn til að fá auðveldari aðgang að þeim."
+ "Stjórnað af fyrirtækinu þínu"
+ "Slökkt er á tilkynningum og forritum"
+ "Loka"
+ "Lokað"
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index a52aee4295..28a8f93564 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -40,13 +40,18 @@
"Nessuna app trovata corrispondente a \"%1$s\""
"Cerca altre app"
"Notifiche"
+ "Tocca e tieni premuto per scegliere la scorciatoia"
+ "Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate."
"Spazio nella schermata Home esaurito."
"Spazio esaurito nella barra dei Preferiti"
"Elenco di app"
+ "Elenco di app personali"
+ "Elenco di app di lavoro"
"Home page"
"Rimuovi"
"Disinstalla"
"Informazioni app"
+ "Installa"
"aggiunta di scorciatoie"
"Consente a un\'app di aggiungere scorciatoie automaticamente."
"lettura di impostazioni e scorciatoie in Home"
@@ -59,6 +64,10 @@
"Questa è un\'app di sistema e non può essere disinstallata."
"Cartella senza nome"
"App %1$s disattivata"
+
+ - %1$s ha %2$d notifiche
+ - %1$s ha %2$d notifica
+
"Pagina %1$d di %2$d"
"Schermata Home %1$d di %2$d"
"Nuova pagina Schermata Home"
@@ -72,19 +81,19 @@
"Sfondi"
"Impostazioni Home"
"Disattivata dall\'amministratore"
- "Panoramica"
"Consenti rotazione della schermata Home"
"Con il telefono ruotato"
- "L\'impostazione corrente del display non consente la rotazione"
"Indicatori notifica"
"Attiva"
"Non attiva"
"Accesso alle notifiche necessario"
"Per mostrare gli indicatori di notifica, attiva le notifiche per l\'app %1$s"
"Modifica impostazioni"
+ "Mostra indicatori di notifica"
"Aggiungi icone alla schermata Home"
"Per le nuove app"
"Cambia la forma delle icone"
+ "nella schermata Home"
"Usa impostazione predefinita di sistema"
"Quadrato"
"Supercerchio"
@@ -99,6 +108,8 @@
"Download di %1$s in corso, %2$s completato"
"%1$s in attesa di installazione"
"Widget di %1$s"
+ "Elenco di widget"
+ "Elenco di widget chiuso"
"Aggiungi a schermata Home"
"Sposta elemento qui"
"Elemento aggiunto alla schermata Home"
@@ -114,9 +125,6 @@
"Crea cartella con: %1$s"
"Cartella creata"
"Sposta nella schermata Home"
- "Sposta schermata a sinistra"
- "Sposta schermata a destra"
- "Schermata spostata"
"Ridimensiona"
"Aumenta larghezza"
"Aumenta altezza"
@@ -124,8 +132,16 @@
"Riduci altezza"
"Widget ridimensionato a larghezza %1$s, altezza %2$s"
"Scorciatoie"
- "%1$d scorciatoie per %2$s"
- "%1$d scorciatoie e %2$d notifiche relative a %3$s"
+ "Scorciatoie e notifiche"
"Ignora"
"Notifica ignorata"
+ "Personali"
+ "Lavoro"
+ "Profilo di lavoro"
+ "Qui puoi trovare le tue app di lavoro"
+ "Ogni app di lavoro è contrassegnata da un badge e viene tenuta al sicuro dalla tua organizzazione. Sposta le app nella schermata Home per accedervi più facilmente."
+ "Gestito dalla tua organizzazione"
+ "Le notifiche e le app non sono attive"
+ "Chiudi"
+ "Chiusa"
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 650a90db81..d4302c66c3 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -40,13 +40,18 @@
"לא נמצאו אפליקציות התואמות ל-\"%1$s\""
"חפש אפליקציות נוספות"
"הודעות"
+ "כדי להוסיף קיצור דרך, יש לגעת בו ולהחזיק אותו."
+ "כדי להוסיף קיצור דרך או להשתמש בפעולות מותאמות אישית, יש להקיש על קיצור הדרך פעמיים ולהחזיק אותו."
"אין עוד מקום במסך דף הבית הזה."
"אין עוד מקום במגש המועדפים"
"רשימת אפליקציות"
+ "רשימת אפליקציות אישיות"
+ "רשימת אפליקציות עבודה"
"דף הבית"
"הסר"
"הסר התקנה"
"פרטי אפליקציה"
+ "התקנה"
"התקן קיצורי דרך"
"מאפשר לאפליקציה להוסיף קיצורי דרך ללא התערבות המשתמש."
"קרא הגדרות וקיצורי דרך של דף הבית"
@@ -59,6 +64,12 @@
"זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה."
"תיקיה ללא שם"
"%1$s מושבתת"
+
+ - לאפליקציה %1$s יש %2$d הודעות
+ - לאפליקציה %1$s יש %2$d הודעות
+ - לאפליקציה %1$s יש %2$d הודעות
+ - לאפליקציה %1$s יש הודעה אחת (%2$d)
+
"דף %1$d מתוך %2$d"
"מסך דף הבית %1$d מתוך %2$d"
"מסך דף הבית חדש"
@@ -72,19 +83,19 @@
"טפטים"
"הגדרות דף הבית"
"הושבת על ידי מנהל המערכת שלך"
- "סקירה"
"אפשרות סיבוב של מסך דף הבית"
"כאשר הטלפון מסובב"
- "הגדרת התצוגה הנוכחית אינה מאפשרת סיבוב"
"סימני הודעות"
"מופעלת"
"כבויה"
"נדרשת גישה להודעות"
"כדי להציג את סימני ההודעות, יש להפעיל הודעות מהאפליקציה %1$s"
"שנה את ההגדרות"
+ "הצגה של סימן ההודעות"
"הוספת סמל במסך דף הבית"
"לאפליקציות חדשות"
"שינוי הצורה של הסמלים"
+ "במסך דף הבית"
"השתמש בברירת המחדל של המערכת"
"ריבוע"
"ריבוע בעל פינות מעוגלות"
@@ -93,12 +104,14 @@
"משנה את הצורה של הסמלים"
"לא ידוע"
"הסר"
- "חפש"
+ "חיפוש"
"אפליקציה זו אינה מותקנת"
"האפליקציה של סמל זה אינה מותקנת. ניתן להסיר אותו, או לחפש את האפליקציה ולהתקין אותה ידנית."
"מוריד את %1$s, %2$s הושלמו"
"מחכה להתקנה של %1$s"
"ווידג\'טים של %1$s"
+ "רשימת ווידג\'טים"
+ "רשימת הווידג\'טים נסגרה"
"הוסף למסך דף הבית"
"העבר את הפריט לכאן"
"הפריט הועבר אל מסך דף הבית"
@@ -114,9 +127,6 @@
"צור תיקייה עם: %1$s"
"התיקייה נוצרה"
"העבר אל מסך דף הבית"
- "הזז את המסך שמאלה"
- "הזז את המסך ימינה"
- "המסך הועבר"
"שנה גודל"
"הגדל רוחב"
"הגדל גובה"
@@ -124,8 +134,16 @@
"הקטן גובה"
"גודל הווידג\'ט שונה - רוחב %1$s גובה %2$s"
"קיצורי דרך"
- "%1$d קיצורי דרך עבור %2$s"
- "%1$d קיצורי דרך ו-%2$d הודעות של %3$s"
+ "קיצורי דרך והודעות"
"סגור"
"ההודעה נסגרה"
+ "אישיות"
+ "עבודה"
+ "פרופיל עבודה"
+ "ניתן למצוא כאן את אפליקציות העבודה"
+ "לכל אפליקציית עבודה יש תג ואבטחתה מטופלת בידי הארגון. אפשר להעביר אפליקציות אל מסך דף הבית כדי להקל את הגישה אליהן."
+ "מנוהל בידי הארגון"
+ "הודעות ואפליקציות כבויות"
+ "סגירה"
+ "סגור"
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 4071a6cc99..2598d1839e 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -40,13 +40,18 @@
"「%1$s」に一致するアプリは見つかりませんでした"
"他のアプリを検索"
"通知"
+ "ショートカットを追加するには押し続けます。"
+ "ダブルタップ後に押し続けてショートカットを選択するか、カスタム操作を使用してください。"
"このホーム画面に空きスペースがありません。"
"お気に入りトレイに空きスペースがありません"
"アプリのリスト"
+ "個人用アプリのリスト"
+ "仕事用アプリのリスト"
"ホーム"
"削除"
"アンインストール"
"アプリ情報"
+ "インストール"
"ショートカットのインストール"
"ユーザー操作なしでショートカットを追加することをアプリに許可します。"
"ホームの設定とショートカットの読み取り"
@@ -59,6 +64,10 @@
"このシステムアプリはアンインストールできません。"
"名前のないフォルダ"
"「%1$s」は無効です"
+
+ - %1$s: %2$d 件の通知
+ - %1$s: %2$d 件の通知
+
"%1$d/%2$dページ"
"ホーム画面: %1$d/%2$d"
"新しいホーム画面ページ"
@@ -72,19 +81,19 @@
"壁紙"
"ホームの設定"
"管理者により無効にされています"
- "概要"
"ホーム画面の回転を許可"
"スマートフォンが回転したとき"
- "現在の [ディスプレイ] 設定では回転を使用できません"
"通知ドット"
"ON"
"OFF"
"通知へのアクセス権限が必要"
"通知ドットを表示するには、「%1$s」のアプリ通知を ON にしてください"
"設定を変更"
+ "通知ドットの表示"
"ホーム画面にアイコンを追加"
- "新しいアプリをダウンロードしたときに"
+ "新しいアプリをダウンロードしたとき"
"アイコンの形の変更"
+ "ホーム画面上"
"システムのデフォルトを使用"
"スクエア"
"スクワークル"
@@ -99,6 +108,8 @@
"%1$sをダウンロード中、%2$s完了"
"%1$sのインストール待ち"
"%1$sのウィジェット"
+ "ウィジェット リスト"
+ "ウィジェット リストを閉じました"
"ホーム画面に追加"
"アイテムをここに移動"
"アイテムをホーム画面に追加しました"
@@ -114,9 +125,6 @@
"「%1$s」フォルダを作成"
"フォルダを作成しました"
"ホーム画面に移動"
- "画面を左に移動"
- "画面を右に移動"
- "画面を移動しました"
"サイズを変更"
"幅を広くする"
"高さを高くする"
@@ -124,8 +132,16 @@
"高さを低くする"
"ウィジェットのサイズを幅%1$s、高さ%2$sに変更しました"
"ショートカット"
- "%2$s用の %1$d 件のショートカット"
- "%3$s: %1$d 個のショートカットと %2$d 件の通知"
+ "ショートカットと通知"
"表示しない"
"通知を非表示にしました"
+ "個人用"
+ "仕事用"
+ "仕事用プロファイル"
+ "ここには仕事用アプリが表示されます"
+ "仕事用アプリにはバッジが表示され、組織によって安全に保護されています。仕事用アプリをホーム画面に移動すると、簡単にアクセスできます。"
+ "組織によって管理されています"
+ "通知とアプリは OFF です"
+ "閉じる"
+ "終了"
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000000..521ec80f8c
--- /dev/null
+++ b/res/values-ka-rGE/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "სამუშაო"
+ "აპი არ არის დაყენებული."
+ "აპი მიუწვდომელია"
+ "უსაფრთხო რეჟიმში ჩამოტვირთული აპი გაუქმებულია"
+ "უსაფრთხო რეჟიმში ვიჯეტი გამორთულია"
+ "მალსახმობი მიუწვდომელია"
+ "მთავარი ეკრანი"
+ "მორგებული ქმედებები"
+ "შეეხეთ და დააყოვნეთ ვიჯეტის ასარჩევად."
+ "ორმაგად შეეხეთ და გეჭიროთ ვიჯეტის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."
+ "%1$d × %2$d"
+ "სიგრძე: %1$d, სიგანე: %2$d"
+ "ხანგრძლივად შეეხეთ ხელით განსათავსებლად"
+ "ავტომატურად დამატება"
+ "აპების ძიება"
+ "აპები იტვირთება…"
+ "„%1$s“-ის თანხვედრი აპები არ მოიძებნა"
+ "მეტი აპის პოვნა"
+ "შეტყობინებები"
+ "შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."
+ "ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."
+ "ამ მთავარ ეკრანზე ადგილი აღარ არის."
+ "რჩეულების თაროზე ადგილი არ არის"
+ "აპების სია"
+ "პერსონალური აპების სია"
+ "სამსახურის აპების სია"
+ "მთავარი"
+ "ამოშლა"
+ "დეინსტალაცია"
+ "აპის შესახებ"
+ "ინსტალაცია"
+ "მალსახმობების დაყენება"
+ "აპისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."
+ "მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვა"
+ "აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვის უფლების მიცემა."
+ "მთავარი ეკრანის პარამეტრებისა და მალსახმობების ჩაწერა"
+ "აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების შეცვლის უფლების მიცემა."
+ "%1$s-ს არ აქვს სატელეფონო ზარების განხორციელების უფლება"
+ "პრობლემა ვიჯეტის ჩატვირთვისას"
+ "დაყენება"
+ "ეს სისტემური აპია და მისი წაშლა შეუძლებელია."
+ "უსახელო საქაღალდე"
+ "%1$s გაითიშა"
+
+ - %1$s-ში %2$d შეტყობინებაა
+ - %1$s-ში %2$d შეტყობინებაა
+
+ "გვერდი %1$d %2$d-დან"
+ "მთავარი ეკრანი %1$d, %2$d-დან"
+ "მთავარი ეკრანის ახალი გვერდი"
+ "საქაღალდე გახსნილია, %1$d x %2$d"
+ "შეეხეთ საქაღალდის დასახურად"
+ "შეეხეთ გადარქმეული სახელის შესანახად"
+ "საქაღალდე დაიხურა"
+ "საქაღალდეს შეეცვალა სახელი „%1$s“-ად"
+ "საქაღალდე: %1$s"
+ "ვიჯეტები"
+ "ფონები"
+ "მთავარი გვერდის პარამეტრები"
+ "გათიშულია თქვენი ადმინისტრატორის მიერ"
+ "მთავარი ეკრანის შეტრიალების დაშვება"
+ "ტელეფონის შეტრიალებისას"
+ "შეტყობინების ნიშნულები"
+ "ჩართული"
+ "გამორთული"
+ "საჭიროა შეტყობინებებზე წვდომა"
+ "შეტყობინებათა ნიშნულების საჩვენებლად, ჩართეთ აპის შეტყობინებები %1$s-ისთვის"
+ "პარამეტრების შეცვლა"
+ "შეტყობინების ნიშნულების ჩვენება"
+ "ხატულას მთავარ ეკრანზე დამატება"
+ "ახალი აპებისთვის"
+ "ხატულას ფორმის შეცვლა"
+ "მთავარ ეკრანზე"
+ "ნაგულისხმევი სისტემური პარამეტრების გამოყენება"
+ "კვადრატი"
+ "წრეკუთხედი"
+ "წრე"
+ "წვეთი"
+ "მიმდინარეობს ხატულას ფორმის ცვლილებების მიყენება"
+ "უცნობი"
+ "ამოშლა"
+ "ძიება"
+ "ეს აპი დაყენებული არ არის"
+ "ამ ხატულის აპი დაყენებული არ არის. შეგიძლიათ ამოშალოთ, ან მოიძიოთ აპი და ხელით მოახდინოთ მისი ინსტალაცია."
+ "მიმდინარეობს %1$s-ის ჩამოტვირთვა, %2$s დასრულდა"
+ "%1$s ელოდება ინსტალაციას"
+ "%1$s-ის ვიჯეტები"
+ "მთავარ ეკრანზე დამატება"
+ "ერთეულის გადაადგილება აქ"
+ "ერთეული დაემატა მთავარ ეკრანს"
+ "ერთეული წაიშალა"
+ "ერთეულის გადაადგილება"
+ "გადატანა რიგში %1$s სვეტში %2$s"
+ "გადატანა %1$s პოზიციაზე"
+ "გადატანა რჩეულთა პოზიციაზე %1$s"
+ "ერთეული გადაადგილდა"
+ "საქაღალდეში დამატება: %1$s"
+ "საქაღალდეში დამატება %1$s-ით"
+ "ერთეული დაემატა საქაღალდეს"
+ "საქაღალდის შექმნა ერთეულით: %1$s"
+ "საქაღალდე შექმნილია"
+ "მთავარ ეკრანზე გადატანა"
+ "ზომის შეცვლა"
+ "სიგანის გაზრდა"
+ "სიმაღლის გაზრდა"
+ "სიგანის შემცირება"
+ "სიმაღლის შემცირება"
+ "ვიჯეტის ზომები შეიცვალა: სიგანე %1$s სიმაღლე %2$s"
+ "მალსახმობები"
+ "%2$s-ს აქვს %1$d მალსახმობი"
+ "%3$s-ის %1$d მალსახმობი და %2$d შეტყობინება"
+ "დახურვა"
+ "შეტყობინება დაიხურა"
+ "პირადი"
+ "სამსახური"
+ "სამსახურის პროფილი"
+ "აქ თავმოყრილია სამსახურის აპები"
+ "სამსახურის თითოეულ აპს აქვს ბეჯი, რაც ნიშნავს, რომ მათ უსაფრთხოებას თქვენი ორგანიზაცია უზრუნველყოფს. მარტივი წვდომისთვის, შეგიძლიათ სამსახურის აპები მთავარი ეკრანზე გადაიტანოთ."
+ "იმართება თქვენი ორგანიზაციის მიერ"
+ "შეტყობინებები და აპები გამორთულია"
+ "დახურვა"
+ "დახურული"
+
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 7e8b46ce88..3bdbab7423 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -40,13 +40,18 @@
"„%1$s“-ის თანხვედრი აპები არ მოიძებნა"
"მეტი აპის პოვნა"
"შეტყობინებები"
+ "შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."
+ "ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."
"ამ მთავარ ეკრანზე ადგილი აღარ არის."
"რჩეულების თაროზე ადგილი არ არის"
"აპების სია"
+ "პერსონალური აპების სია"
+ "სამსახურის აპების სია"
"მთავარი"
"ამოშლა"
"დეინსტალაცია"
"აპის შესახებ"
+ "ინსტალაცია"
"მალსახმობების დაყენება"
"აპისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."
"მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვა"
@@ -59,6 +64,10 @@
"ეს სისტემური აპია და მისი წაშლა შეუძლებელია."
"უსახელო საქაღალდე"
"%1$s გაითიშა"
+
+ - %1$s-ში %2$d შეტყობინებაა
+ - %1$s-ში %2$d შეტყობინებაა
+
"გვერდი %1$d %2$d-დან"
"მთავარი ეკრანი %1$d, %2$d-დან"
"მთავარი ეკრანის ახალი გვერდი"
@@ -72,19 +81,19 @@
"ფონები"
"მთავარი გვერდის პარამეტრები"
"გათიშულია თქვენი ადმინისტრატორის მიერ"
- "მიმოხილვა"
"მთავარი ეკრანის შეტრიალების დაშვება"
"ტელეფონის შეტრიალებისას"
- "ბრუნვა დაუშვებელია ჩვენების მიმდინარე პარამეტრებით"
"შეტყობინების ნიშნულები"
"ჩართული"
"გამორთული"
"საჭიროა შეტყობინებებზე წვდომა"
"შეტყობინებათა ნიშნულების საჩვენებლად, ჩართეთ აპის შეტყობინებები %1$s-ისთვის"
"პარამეტრების შეცვლა"
+ "შეტყობინების ნიშნულების ჩვენება"
"ხატულას მთავარ ეკრანზე დამატება"
"ახალი აპებისთვის"
"ხატულას ფორმის შეცვლა"
+ "მთავარ ეკრანზე"
"ნაგულისხმევი სისტემური პარამეტრების გამოყენება"
"კვადრატი"
"წრეკუთხედი"
@@ -99,6 +108,8 @@
"მიმდინარეობს %1$s-ის ჩამოტვირთვა, %2$s დასრულდა"
"%1$s ელოდება ინსტალაციას"
"%1$s-ის ვიჯეტები"
+ "ვიჯეტების სია"
+ "ვიჯეტების სია დაიხურა"
"მთავარ ეკრანზე დამატება"
"ერთეულის გადაადგილება აქ"
"ერთეული დაემატა მთავარ ეკრანს"
@@ -114,9 +125,6 @@
"საქაღალდის შექმნა ერთეულით: %1$s"
"საქაღალდე შექმნილია"
"მთავარ ეკრანზე გადატანა"
- "ეკრანის გადატანა მარცხნივ"
- "ეკრანის გადატანა მარჯვნით"
- "ეკრანი გადაადგილდა"
"ზომის შეცვლა"
"სიგანის გაზრდა"
"სიმაღლის გაზრდა"
@@ -124,8 +132,16 @@
"სიმაღლის შემცირება"
"ვიჯეტის ზომები შეიცვალა: სიგანე %1$s სიმაღლე %2$s"
"მალსახმობები"
- "%2$s-ს აქვს %1$d მალსახმობი"
- "%3$s-ის %1$d მალსახმობი და %2$d შეტყობინება"
+ "მალსახმობები და შეტყობინებები"
"დახურვა"
"შეტყობინება დაიხურა"
+ "პირადი"
+ "სამსახური"
+ "სამსახურის პროფილი"
+ "აქ თავმოყრილია სამსახურის აპები"
+ "სამსახურის თითოეულ აპს აქვს ბეჯი, რაც ნიშნავს, რომ მათ უსაფრთხოებას თქვენი ორგანიზაცია უზრუნველყოფს. მარტივი წვდომისთვის, შეგიძლიათ სამსახურის აპები მთავარი ეკრანზე გადაიტანოთ."
+ "იმართება თქვენი ორგანიზაციის მიერ"
+ "შეტყობინებები და აპები გამორთულია"
+ "დახურვა"
+ "დახურული"
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
new file mode 100644
index 0000000000..7ab73d95dd
--- /dev/null
+++ b/res/values-kk-rKZ/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Жұмыс"
+ "Қолданба орнатылмаған."
+ "Қолданба қол жетімді емес"
+ "Жүктелген қолданба қауіпсіз режимде өшірілген"
+ "Қауіпсіз режимде виджеттер өшіріледі"
+ "Таңбаша қолжетімді емес"
+ "Негізгі экран"
+ "Арнаулы әрекеттер"
+ "Виджетті таңдау үшін түртіп, мықтап ұстаңыз."
+ "Виджетті таңдау немесе арнаулы әрекеттерді таңдау үшін екі рет түртіп, ұстап тұрыңыз."
+ "%1$d × %2$d"
+ "Ені: %1$d, биіктігі: %2$d"
+ "Қолмен қою үшін басып тұрыңыз"
+ "Автоматты енгізу"
+ "Қолданбаларды іздеу"
+ "Қолданбалар жүктелуде…"
+ "\"%1$s\" сұрауына сәйкес келетін қолданбалар жоқ"
+ "Қосымша қолданбалар іздеу"
+ "Хабарландырулар"
+ "Таңбашаны таңдау үшін оны басып, ұстап тұрыңыз."
+ "Екі рет басып, ұстап тұрып, таңбашаны таңдаңыз немесе арнаулы әрекеттерді пайдаланыңыз."
+ "Бұл Негізгі экранда орын қалмады."
+ "Қалаулылар науасында орын қалмады"
+ "Қолданбалар тізімі"
+ "Жеке қолданбалар тізімі"
+ "Жұмыс қолданбаларының тізімі"
+ "Негізгі"
+ "Жою"
+ "Жою"
+ "Қолданба ақпараты"
+ "Орнату"
+ "төте пернелерді орнату"
+ "Қолданбаға пайдаланушының қатысуынсыз төте пернелерді қосу мүмкіндігін береді."
+ "Негізгі экрандағы параметрлер мен төте пернелерді оқу"
+ "Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді оқу мүмкіндігін береді."
+ "Негізгі экран параметрлері мен төте пернелерін жазу"
+ "Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді өзгерту мүмкіндігін береді."
+ "%1$s арқылы телефон қоңырауларын соғуға рұқсат етілмеген"
+ "Виджетті жүктеу барысында мәселе орын алды"
+ "Орнату"
+ "Бұл жүйе қолданбасы, сондықтан оны алу мүмкін емес."
+ "Атауы жоқ қалта"
+ "%1$s өшірілді"
+
+ - %1$s қолданбасында %2$d хабарландыру бар
+ - %1$s қолданбасында %2$d хабарландыру бар
+
+ "%1$d бет, барлығы %2$d"
+ "%1$d негізгі экран, барлығы %2$d"
+ "Жаңа негізгі экран беті"
+ "Қалта ашылды, %1$d және %2$d"
+ "Қалтаны жабу үшін түртіңіз"
+ "Қайта атауды сақтау үшін түртіңіз"
+ "Қалта жабылды"
+ "Қалта атауы %1$s болып өзгертілді"
+ "Қалта: %1$s"
+ "Виджеттер"
+ "Тұсқағаздар"
+ "Негізгі экран параметрлері"
+ "Әкімші өшірді"
+ "Негізгі экранның бұрылуына рұқсат ету"
+ "Телефон бұрылғанда"
+ "Хабарландыру белгілері"
+ "Қосулы"
+ "Өшірулі"
+ "Хабарландыруға кіру рұқсаты қажет"
+ "Хабарландыру белгілерін көрсету үшін %1$s қолданбасының қолданба хабарландыруларын қосыңыз"
+ "Параметрлерді өзгерту"
+ "Хабарландыру белгілерін көрсету"
+ "Негізгі экранға белгіше енгізу"
+ "Жаңа қолданбаларға арналған"
+ "Белгіше пішінін өзгерту"
+ "Негізгі экранда"
+ "Жүйенің әдепкі параметрін пайдалану"
+ "Шаршы"
+ "Жұмыр төртбұрыш"
+ "Шеңбер"
+ "Тамшы"
+ "Белгіше пішіні өзгерістері күшіне енуде"
+ "Белгісіз"
+ "Алып тастау"
+ "Іздеу"
+ "Бұл қолданба орнатылмаған"
+ "Осы белгіше үшін қолданба орнатылмаған. Оны жоюға болады немесе қолданбаны іздеп, қолмен орнатуға болады."
+ "%1$s жүктелуде, %2$s аяқталды"
+ "%1$s орнату күтілуде"
+ "%1$s виджеті"
+ "Негізгі экранға қосу"
+ "Элементті мұнда жылжыту"
+ "Элемент негізгі экранға қосылды"
+ "Элемент жойылды"
+ "Элементті жылжыту"
+ "%1$s-жол, %2$s-бағанға жылжыту"
+ "%1$s-орынға жылжыту"
+ "%1$s нөмірлі таңдаулы орынға жылжыту"
+ "Элемент жылжытылды"
+ "Қалтаға қосу: %1$s"
+ "%1$s бар қалтаға қосу"
+ "Элемент қалтаға қосылды"
+ "Мына бар қалтаны жасау: %1$s"
+ "Қалта жасалды"
+ "Негізгі экранға жылжыту"
+ "Өлшемін өзгерту"
+ "Енін арттыру"
+ "Биіктігін арттыру"
+ "Енін азайту"
+ "Биіктігін азайту"
+ "Виджет өлшемінің ені %1$s, биіктігі %2$s болып өзгертілді"
+ "Таңбашалар"
+ "%2$s қолданбасына арналған %1$d таңбаша"
+ "%3$s қолданбасының %1$d таңбашасы мен %2$d хабарландыруы"
+ "Бас тарту"
+ "Хабарландырудан бас тартылды"
+ "Жеке"
+ "Жұмыс"
+ "Жұмыс профилі"
+ "Жұмыс қолданбалары осы жерде берілген"
+ "Әрбір жұмыс қолданбасында танымбелгі бар. Ол оның қауіпсіздігі ұйым арқылы қамтамасыз етілетінін білдіреді. Жұмыс қолданбаларына оңай кіру үшін, оларды Негізгі экранға жылжытуға болады."
+ "Ұйым арқылы басқарылады"
+ "Хабарландырулар мен қолданбалар өшірулі"
+ "Жабу"
+ "Жабық"
+
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 50ed9aa680..98afcccfe0 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" сұрауына сәйкес келетін қолданбалар жоқ"
"Қосымша қолданбалар іздеу"
"Хабарландырулар"
+ "Таңбашаны таңдау үшін оны басып, ұстап тұрыңыз."
+ "Екі рет басып, ұстап тұрып, таңбашаны таңдаңыз немесе арнаулы әрекеттерді пайдаланыңыз."
"Бұл Негізгі экранда орын қалмады."
"Қалаулылар науасында орын қалмады"
"Қолданбалар тізімі"
+ "Жеке қолданбалар тізімі"
+ "Жұмыс қолданбаларының тізімі"
"Негізгі"
"Жою"
"Жою"
"Қолданба ақпараты"
+ "Орнату"
"төте пернелерді орнату"
"Қолданбаға пайдаланушының қатысуынсыз төте пернелерді қосу мүмкіндігін береді."
"Негізгі экрандағы параметрлер мен төте пернелерді оқу"
@@ -59,6 +64,10 @@
"Бұл жүйе қолданбасы, сондықтан оны алу мүмкін емес."
"Атауы жоқ қалта"
"%1$s өшірілді"
+
+ - %1$s қолданбасында %2$d хабарландыру бар
+ - %1$s қолданбасында %2$d хабарландыру бар
+
"%1$d бет, барлығы %2$d"
"%1$d негізгі экран, барлығы %2$d"
"Жаңа негізгі экран беті"
@@ -72,19 +81,19 @@
"Тұсқағаздар"
"Негізгі экран параметрлері"
"Әкімші өшірді"
- "Шолу"
"Негізгі экранның бұрылуына рұқсат ету"
"Телефон бұрылғанда"
- "Экранның ағымдағы параметрі айналуға рұқсат бермейді"
"Хабарландыру белгілері"
"Қосулы"
"Өшірулі"
"Хабарландыруға кіру рұқсаты қажет"
"Хабарландыру белгілерін көрсету үшін %1$s қолданбасының қолданба хабарландыруларын қосыңыз"
"Параметрлерді өзгерту"
+ "Хабарландыру белгілерін көрсету"
"Негізгі экранға белгіше енгізу"
"Жаңа қолданбаларға арналған"
"Белгіше пішінін өзгерту"
+ "Негізгі экранда"
"Жүйенің әдепкі параметрін пайдалану"
"Шаршы"
"Жұмыр төртбұрыш"
@@ -99,6 +108,8 @@
"%1$s жүктелуде, %2$s аяқталды"
"%1$s орнату күтілуде"
"%1$s виджеті"
+ "Виджеттер тізімі"
+ "Видджеттер тізімі жабылды"
"Негізгі экранға қосу"
"Элементті мұнда жылжыту"
"Элемент негізгі экранға қосылды"
@@ -114,9 +125,6 @@
"Мына бар қалтаны жасау: %1$s"
"Қалта жасалды"
"Негізгі экранға жылжыту"
- "Экранды солға жылжыту"
- "Экранды оңға жылжыту"
- "Экран жылжытылды"
"Өлшемін өзгерту"
"Енін арттыру"
"Биіктігін арттыру"
@@ -124,8 +132,16 @@
"Биіктігін азайту"
"Виджет өлшемінің ені %1$s, биіктігі %2$s болып өзгертілді"
"Таңбашалар"
- "%2$s қолданбасына арналған %1$d таңбаша"
- "%3$s қолданбасының %1$d таңбашасы мен %2$d хабарландыруы"
+ "Таңбашалар мен хабарландырулар"
"Бас тарту"
"Хабарландырудан бас тартылды"
+ "Жеке"
+ "Жұмыс"
+ "Жұмыс профилі"
+ "Жұмыс қолданбалары осы жерде берілген"
+ "Әрбір жұмыс қолданбасында танымбелгі бар. Ол оның қауіпсіздігі ұйым арқылы қамтамасыз етілетінін білдіреді. Жұмыс қолданбаларына оңай кіру үшін, оларды Негізгі экранға жылжытуға болады."
+ "Ұйым арқылы басқарылады"
+ "Хабарландырулар мен қолданбалар өшірулі"
+ "Жабу"
+ "Жабық"
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000000..582bb33dd2
--- /dev/null
+++ b/res/values-km-rKH/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "ការងារ"
+ "មិនបានដំឡើងកម្មវិធី។"
+ "មិនមានកម្មវិធី"
+ "បានបិទកម្មវិធីដែលបានទាញយកក្នុងរបៀបសុវត្ថិភាព"
+ "បានបិទធាតុក្រាហ្វិកក្នុងរបៀបសុវត្ថិភាព"
+ "ផ្លូវកាត់មិនអាចប្រើបានទេ"
+ "អេក្រង់ដើម"
+ "សកម្មភាពផ្ទាល់ខ្លួន"
+ "ប៉ះ & សង្កត់ ដើម្បីជ្រើសធាតុក្រាហ្វិក។"
+ "ប៉ះពីរដង ហើយចុចឲ្យជាប់ដើម្បីជ្រើសយកធាតុក្រាហ្វិក ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"
+ "%1$d × %2$d"
+ "ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"
+ "ចុចឲ្យជាប់ដើម្បីបញ្ចូលវាដោយផ្ទាល់"
+ "បញ្ចូលដោយស្វ័យប្រវត្តិ"
+ "ស្វែងរកកម្មវិធី"
+ "កំពុងផ្ទុកកម្មវិធី…"
+ "រកមិនឃើញកម្មវិធីដែលត្រូវគ្នាជាមួយ \"%1$s\" ទេ"
+ "ស្វែងរកកម្មវិធីច្រើនទៀត"
+ "ការជូនដំណឹង"
+ "ចុចឱ្យជាប់ដើម្បីជ្រើសរើសផ្លូវកាត់មួយ។"
+ "ចុចពីរដង ហើយចុចឱ្យជាប់ដើម្បីជ្រើសរើសផ្លូវកាត់មួយ ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"
+ "គ្មានបន្ទប់នៅលើអេក្រង់ដើមនេះទៀតទេ។"
+ "គ្មានបន្ទប់ក្នុងថាសនិយមប្រើ"
+ "បញ្ជីកម្មវិធី"
+ "បញ្ជីកម្មវិធីផ្ទាល់ខ្លួន"
+ "បញ្ជីកម្មវិធីការងារ"
+ "ដើម"
+ "យកចេញ"
+ "លុបការដំឡើង"
+ "ព័ត៌មានកម្មវិធី"
+ "ដំឡើង"
+ "ដំឡើងផ្លូវកាត់"
+ "អនុញ្ញាតឲ្យកម្មវិធីបន្ថែមផ្លូវកាត់ ដោយមិនចាំបាច់អំពើពីអ្នកប្រើ។"
+ "អានការកំណត់ និងផ្លូវកាត់អេក្រង់ដើម"
+ "អនុញ្ញាតឲ្យកម្មវិធីអានការកំណត់ និងផ្លូវកាត់ក្នុងអេក្រង់ដើម។"
+ "សរសេរការកំណត់ និងផ្លូវកាត់លើអេក្រង់ដើម"
+ "អនុញ្ញាតឲ្យកម្មវិធីប្ដូរការកំណត់ និងផ្លូវកាត់ក្នុងអេក្រង់ដើម។"
+ "%1$s មិនត្រូវបានអនុញ្ញាតឲ្យធ្វើការហៅទូរស័ព្ទទេ"
+ "បញ្ហាក្នុងការផ្ទុកធាតុក្រាហ្វិក"
+ "រៀបចំ"
+ "នេះជាកម្មវិធីប្រព័ន្ធ មិនអាចលុបបានទេ។"
+ "ថតគ្មានឈ្មោះ"
+ "បានបិទដំណើរការ %1$s"
+
+ - %1$s មានការជូនដំណឹង %2$d
+ - %1$s មានការជូនដំណឹង %2$d
+
+ "ទំព័រ %1$d នៃ %2$d"
+ "អេក្រង់ដើម %1$d នៃ %2$d"
+ "ទំព័រអេក្រង់ដើមថ្មី"
+ "បានបើកថត %1$d ដោយ %2$d"
+ "ប៉ះ ដើម្បីបិទថត"
+ "ប៉ះដើម្បីរក្សាទុកឈ្មោះដែលបានប្តូរ"
+ "បានបិទថត"
+ "បានប្ដូរឈ្មោះថតជា %1$s"
+ "ថត៖ %1$s"
+ "ធាតុក្រាហ្វិក"
+ "ផ្ទាំងរូបភាព"
+ "ការកំណត់ទំព័រដើម"
+ "បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"
+ "អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"
+ "នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"
+ "ស្លាកជូនដំណឹង"
+ "បើក"
+ "បិទ"
+ "តម្រូវឲ្យមានសិទ្ធិចូលប្រើប្រាស់ការជូនដំណឹង"
+ "ដើម្បីបង្ហាញស្លាកជូនដំណឹង សូមបើកការជូនដំណឹងកម្មវិធីសម្រាប់ %1$s"
+ "ប្ដូរការកំណត់"
+ "បង្ហាញស្លាកជូនដំណឹង"
+ "បញ្ចូលរូបតំណាងទៅអេក្រង់ដើម"
+ "សម្រាប់កម្មវិធីថ្មី"
+ "ប្តូររូបរាងរូបតំណាង"
+ "នៅលើអេក្រង់ដើម"
+ "ប្រើលំនាំដើមរបស់ប្រព័ន្ធ"
+ "ការ៉េ"
+ "ការ៉េជ្រុងកោង"
+ "រង្វង់"
+ "តំណក់ទឹកភ្នែក"
+ "កំពុងអនុវត្តការប្តូររូបរាងរូបតំណាង"
+ "មិនស្គាល់"
+ "លុបចេញ"
+ "ស្វែងរក"
+ "មិនបានដំឡើងកម្មវិធីនេះ"
+ "មិនបានដំឡើងកម្មវិធីសម្រាប់រូបតំណាងនេះ។ អ្នកអាចលុបវា ឬស្វែងរកកម្មវិធី និងដំឡើងវាដោយដៃ។"
+ "កំពុងដោនឡូត %1$s បានបញ្ចប់ %2$s"
+ "%1$s កំពុងរង់ចាំការដំឡើង"
+ "ធាតុក្រាហ្វិក %1$s"
+ "បន្ថែមទៅអេក្រង់ដើម"
+ "ផ្លាស់ធាតុមកទីនេះ"
+ "ធាតុដែលត្រូវបានបន្ថែមទៅអេក្រង់ដើម"
+ "ធាតុដែលបានដកចេញ"
+ "ផ្លាស់ទីធាតុ"
+ "ផ្លាស់ទីទៅជួរដេកទី %1$s ជួរឈរទី %2$s"
+ "ផ្លាស់ទីទៅទីតាំង %1$s"
+ "ផ្លាស់ទីទៅការចូលចិត្តទីតាំងទី %1$s"
+ "បានផ្លាស់ទីធាតុ"
+ "បន្ថែមទៅថតឯកសារ៖ %1$s"
+ "បន្ថែមទៅថតឯកសារដែលមានឈ្មោះ %1$s"
+ "បានបន្ថែមធាតុទៅថតឯកសារ"
+ "បង្កើតថតឯកសារជាមួយ៖ %1$s"
+ "បានបង្កើតថតឯកសារ"
+ "ផ្លាស់ទៅអេក្រង់ដើម"
+ "ប្ដូរទំហំ"
+ "បង្កើនទទឹង"
+ "បង្កើនកម្ពស់"
+ "បន្ថយទទឹង"
+ "បន្ថយកម្ពស់"
+ "ធាតុក្រាហ្វិកដែលបានប្តូរទំហំទៅទទឹងប្រវែង %1$s កម្ពស់ប្រវែង %2$s"
+ "ផ្លូវកាត់"
+ "%1$d ផ្លូវកាត់សម្រាប់ %2$s"
+ "ផ្លូវកាត់ចំនួន %1$d និងការជូនដំណឹងចំនួន %2$d សម្រាប់ %3$s"
+ "បដិសេធ"
+ "បានបដិសេធការជូនដំណឹង"
+ "ផ្ទាល់ខ្លួន"
+ "ការងារ"
+ "កម្រងព័ត៌មានការងារ"
+ "ស្វែងរកកម្មវិធីការងារនៅទីនេះ"
+ "កម្មវិធីការងារនីមួយៗមានស្លាកមួយ និងត្រូវបានរក្សាទុកយ៉ាងមានសុវត្ថិភាពដោយស្ថាប័នរបស់អ្នក។ សូមផ្លាស់ទីកម្មវិធីទៅកាន់អេក្រង់ដើមរបស់អ្នក ដើម្បីងាយស្រួលចូលប្រើជាងមុន។"
+ "គ្រប់គ្រងដោយស្ថាប័នរបស់អ្នក"
+ "ការជូនដំណឹង និងកម្មវិធីត្រូវបានបិទ"
+ "បិទ"
+ "បានបិទ"
+
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 7028f7e3ae..ba8d775a62 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -40,13 +40,18 @@
"រកមិនឃើញកម្មវិធីដែលត្រូវគ្នាជាមួយ \"%1$s\" ទេ"
"ស្វែងរកកម្មវិធីច្រើនទៀត"
"ការជូនដំណឹង"
+ "ចុចឱ្យជាប់ដើម្បីជ្រើសរើសផ្លូវកាត់មួយ។"
+ "ចុចពីរដង ហើយចុចឱ្យជាប់ដើម្បីជ្រើសរើសផ្លូវកាត់មួយ ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"
"គ្មានបន្ទប់នៅលើអេក្រង់ដើមនេះទៀតទេ។"
"គ្មានបន្ទប់ក្នុងថាសនិយមប្រើ"
"បញ្ជីកម្មវិធី"
+ "បញ្ជីកម្មវិធីផ្ទាល់ខ្លួន"
+ "បញ្ជីកម្មវិធីការងារ"
"ដើម"
"យកចេញ"
"លុបការដំឡើង"
"ព័ត៌មានកម្មវិធី"
+ "ដំឡើង"
"ដំឡើងផ្លូវកាត់"
"អនុញ្ញាតឲ្យកម្មវិធីបន្ថែមផ្លូវកាត់ ដោយមិនចាំបាច់អំពើពីអ្នកប្រើ។"
"អានការកំណត់ និងផ្លូវកាត់អេក្រង់ដើម"
@@ -59,6 +64,10 @@
"នេះជាកម្មវិធីប្រព័ន្ធ មិនអាចលុបបានទេ។"
"ថតគ្មានឈ្មោះ"
"បានបិទដំណើរការ %1$s"
+
+ - %1$s មានការជូនដំណឹង %2$d
+ - %1$s មានការជូនដំណឹង %2$d
+
"ទំព័រ %1$d នៃ %2$d"
"អេក្រង់ដើម %1$d នៃ %2$d"
"ទំព័រអេក្រង់ដើមថ្មី"
@@ -72,19 +81,19 @@
"ផ្ទាំងរូបភាព"
"ការកំណត់ទំព័រដើម"
"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"
- "សង្ខេប"
"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"
"នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"
- "ការកំណត់អេក្រង់បច្ចុប្បន្នមិនអនុញ្ញាតការបង្វិលទេ"
"ស្លាកជូនដំណឹង"
"បើក"
"បិទ"
"តម្រូវឲ្យមានសិទ្ធិចូលប្រើប្រាស់ការជូនដំណឹង"
"ដើម្បីបង្ហាញស្លាកជូនដំណឹង សូមបើកការជូនដំណឹងកម្មវិធីសម្រាប់ %1$s"
"ប្ដូរការកំណត់"
+ "បង្ហាញស្លាកជូនដំណឹង"
"បញ្ចូលរូបតំណាងទៅអេក្រង់ដើម"
"សម្រាប់កម្មវិធីថ្មី"
"ប្តូររូបរាងរូបតំណាង"
+ "នៅលើអេក្រង់ដើម"
"ប្រើលំនាំដើមរបស់ប្រព័ន្ធ"
"ការ៉េ"
"ការ៉េជ្រុងកោង"
@@ -99,6 +108,8 @@
"កំពុងដោនឡូត %1$s បានបញ្ចប់ %2$s"
"%1$s កំពុងរង់ចាំការដំឡើង"
"ធាតុក្រាហ្វិក %1$s"
+ "បញ្ជីធាតុក្រាហ្វិក"
+ "បានបិទបញ្ជីធាតុក្រាហ្វិក"
"បន្ថែមទៅអេក្រង់ដើម"
"ផ្លាស់ធាតុមកទីនេះ"
"ធាតុដែលត្រូវបានបន្ថែមទៅអេក្រង់ដើម"
@@ -114,9 +125,6 @@
"បង្កើតថតឯកសារជាមួយ៖ %1$s"
"បានបង្កើតថតឯកសារ"
"ផ្លាស់ទៅអេក្រង់ដើម"
- "រំកិលអេក្រង់ទៅខាងឆ្វេង"
- "រំកិលអេក្រង់ទៅខាងស្តាំ"
- "អេក្រង់ដែលបានផ្លាស់ទី"
"ប្ដូរទំហំ"
"បង្កើនទទឹង"
"បង្កើនកម្ពស់"
@@ -124,8 +132,16 @@
"បន្ថយកម្ពស់"
"ធាតុក្រាហ្វិកដែលបានប្តូរទំហំទៅទទឹងប្រវែង %1$s កម្ពស់ប្រវែង %2$s"
"ផ្លូវកាត់"
- "%1$d ផ្លូវកាត់សម្រាប់ %2$s"
- "ផ្លូវកាត់ចំនួន %1$d និងការជូនដំណឹងចំនួន %2$d សម្រាប់ %3$s"
+ "ផ្លូវកាត់ និងការជូនដំណឹង"
"បដិសេធ"
"បានបដិសេធការជូនដំណឹង"
+ "ផ្ទាល់ខ្លួន"
+ "ការងារ"
+ "កម្រងព័ត៌មានការងារ"
+ "ស្វែងរកកម្មវិធីការងារនៅទីនេះ"
+ "កម្មវិធីការងារនីមួយៗមានស្លាកមួយ និងត្រូវបានរក្សាទុកយ៉ាងមានសុវត្ថិភាពដោយស្ថាប័នរបស់អ្នក។ សូមផ្លាស់ទីកម្មវិធីទៅកាន់អេក្រង់ដើមរបស់អ្នក ដើម្បីងាយស្រួលចូលប្រើជាងមុន។"
+ "គ្រប់គ្រងដោយស្ថាប័នរបស់អ្នក"
+ "ការជូនដំណឹង និងកម្មវិធីត្រូវបានបិទ"
+ "បិទ"
+ "បានបិទ"
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
new file mode 100644
index 0000000000..56ebe0a9bb
--- /dev/null
+++ b/res/values-kn-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "ಕೆಲಸ"
+ "ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"
+ "ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ"
+ "ಡೌನ್ಲೋಡ್ ಮಾಡಲಾದ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"
+ "ಸುರಕ್ಷಿತ ಮೋಡ್ನಲ್ಲಿ ವಿಜೆಟ್ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"
+ "ಶಾರ್ಟ್ಕಟ್ ಲಭ್ಯವಿಲ್ಲ"
+ "ಮುಖಪುಟದ ಪರದೆ"
+ "ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳು"
+ "ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ & ಹಿಡಿದುಕೊಳ್ಳಿ."
+ "ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ವಿಜೆಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ"
+ "%1$d × %2$d"
+ "%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"
+ "ಹಸ್ತಚಾಲಿತವಾಗಿ ಸೇರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"
+ "ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೇರಿಸಿ"
+ "ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"
+ "ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."
+ "\"%1$s\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"
+ "ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"
+ "ಅಧಿಸೂಚನೆಗಳು"
+ "ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ."
+ "ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ."
+ "ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."
+ "ಮೆಚ್ಚಿನವುಗಳ ಟ್ರೇನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"
+ "ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"
+ "ವೈಯಕ್ತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"
+ "ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"
+ "ಮುಖಪುಟ"
+ "ತೆಗೆದುಹಾಕಿ"
+ "ಅನ್ಇನ್ಸ್ಟಾಲ್"
+ "ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"
+ "ಸ್ಥಾಪಿಸಿ"
+ "ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"
+ "ಬಳಕೆದಾರರ ಹಸ್ತಕ್ಷೇಪವಿಲ್ಲದೆ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."
+ "ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಓದಿ"
+ "ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."
+ "ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಬರೆಯಿರಿ"
+ "ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."
+ "ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು %1$s ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"
+ "ವಿಜೆಟ್ ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ"
+ "ಸೆಟಪ್"
+ "ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."
+ "ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"
+ "%1$s ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"
+
+ - %1$s, %2$d ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ
+ - %1$s, %2$d ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ
+
+ "%2$d ರಲ್ಲಿ %1$d ಪುಟ"
+ "%2$d ರಲ್ಲಿ %1$d ಮುಖಪುಟದ ಪರದೆ"
+ "ಹೊಸ ಮುಖಪುಟ ಪರದೆ"
+ "ಫೋಲ್ಡರ್ ತೆರೆಯಲಾಗಿದೆ, %1$d ಬೈ %2$d"
+ "ಫೋಲ್ಡರ್ ಮುಚ್ಚಲು ಟ್ಯಾಪ್ ಮಾಡಿ"
+ "ಮರುಹೆಸರನ್ನು ಉಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"
+ "ಫೋಲ್ಡರ್ ಮುಚ್ಚಿದೆ"
+ "ಫೋಲ್ಡರ್ ಅನ್ನು %1$s ಗೆ ಮರುಹೆಸರಿಸಲಾಗಿದೆ"
+ "ಫೋಲ್ಡರ್: %1$s"
+ "ವಿಜೆಟ್ಗಳು"
+ "ವಾಲ್ಪೇಪರ್ಗಳು"
+ "ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್ಗಳು"
+ "ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"
+ "ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"
+ "ಫೋನ್ ತಿರುಗಿಸಿದಾಗ"
+ "ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳು"
+ "ಆನ್"
+ "ಆಫ್"
+ "ಅಧಿಸೂಚನೆ ಪ್ರವೇಶ ಅಗತ್ಯವಿದೆ"
+ "ಅಧಿಸೂಚನೆ ಚುಕ್ಕೆಗಳನ್ನು ತೋರಿಸಲು, %1$s ಗೆ ಅಪ್ಲಿಕೇಶನ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್ ಮಾಡಿ"
+ "ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"
+ "ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳನ್ನು ತೋರಿಸಿ"
+ "ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"
+ "ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ"
+ "ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"
+ "ಮುಖಪುಟ ಪರದೆಯಲ್ಲಿ"
+ "ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ"
+ "ಚೌಕ"
+ "ಚೌಕವೃತ್ತ"
+ "ವೃತ್ತ"
+ "ಕಂಬನಿ"
+ "ಐಕಾನ್ ಆಕಾರ ಬದಲಾವಣೆಯನ್ನು ಅನ್ವಯಿಸಲಾಗುತ್ತಿದೆ"
+ "ಅಪರಿಚಿತ"
+ "ತೆಗೆದುಹಾಕಿ"
+ "ಹುಡುಕಿ"
+ "ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ"
+ "ಈ ಐಕಾನ್ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ. ನೀವು ಅದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಹುಡುಕಬಹುದು ಮತ್ತು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅದನ್ನು ಸ್ಥಾಪಿಸಬಹುದು."
+ "%1$s ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ, %2$s ಪೂರ್ಣಗೊಂಡಿದೆ"
+ "%1$s ಸ್ಥಾಪಿಸಲು ಕಾಯಲಾಗುತ್ತಿದೆ"
+ "%1$s ವಿಜೆಟ್ಗಳು"
+ "ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸು"
+ "ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ"
+ "ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"
+ "ಐಟಂ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"
+ "ಐಟಂ ಸರಿಸಿ"
+ "%1$s ಸಾಲು %2$s ಕಾಲಮ್ಗೆ ಸರಿಸಿ"
+ "%1$s ಸ್ಥಾನಕ್ಕೆ ಸರಿಸಿ"
+ "ಮೆಚ್ಚಿನ %1$s ಸ್ಥಾನಕ್ಕೆ ಸರಿಸಿ"
+ "ಐಟಂ ಸರಿಸಲಾಗಿದೆ"
+ "ಫೋಲ್ಡರ್ಗೆ ಸೇರಿಸಿ: %1$s"
+ "%1$s ಮೂಲಕ ಫೋಲ್ಡರ್ಗೆ ಸೇರಿಸಿ"
+ "ಐಟಂ ಅನ್ನು ಫೋಲ್ಡರ್ಗೆ ಸೇರಿಸಲಾಗಿದೆ"
+ "ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಫೋಲ್ಡರ್ ರಚಿಸಿ: %1$s"
+ "ಫೋಲ್ಡರ್ ರಚಿಸಲಾಗಿದೆ"
+ "ಮುಖಪುಟಕ್ಕೆ ಸರಿಸಿ"
+ "ಮರುಗಾತ್ರ"
+ "ಅಗಲವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"
+ "ಎತ್ತರವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"
+ "ಅಗಲವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"
+ "ಎತ್ತರವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"
+ "ವಿಜೆಟ್ ಅನ್ನು %1$s ಅಗಲ %2$s ಎತ್ತರಕ್ಕೆ ಮರುಗಾತ್ರಗೊಳಿಸಲಾಗಿದೆ"
+ "ಶಾರ್ಟ್ಕಟ್ಗಳು"
+ "%2$s ಗೆ %1$d ಶಾರ್ಟ್ಕಟ್ಗಳು"
+ "%3$s ಗಾಗಿ %1$d ಶಾರ್ಟ್ಕಟ್ಗಳು ಮತ್ತು %2$d ಅಧಿಸೂಚನೆಗಳು"
+ "ವಜಾಗೊಳಿಸಿ"
+ "ಅಧಿಸೂಚನೆಯನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ"
+ "ವೈಯಕ್ತಿಕ"
+ "ಕೆಲಸ"
+ "ಕೆಲಸದ ಪ್ರೊಫೈಲ್"
+ "ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಇಲ್ಲಿ ಹುಡುಕಿ"
+ "ಕೆಲಸದ ಪ್ರತಿ ಅಪ್ಲಿಕೇಶನ್ ಬ್ಯಾಡ್ಜ್ ಹೊಂದಿದೆ ಮತ್ತು ನಿಮ್ಮ ಸಂಸ್ಥೆಯಿಂದ ಸುರಕ್ಷಿತವಾಗಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಸುಲಭ ಪ್ರವೇಶಕ್ಕಾಗಿ ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸರಿಸಿ."
+ "ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ"
+ "ಅಧಿಸೂಚನೆಗಳು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್ಗಳು ಆಫ್ ಆಗಿವೆ"
+ "ಮುಚ್ಚಿ"
+ "ಮುಚ್ಚಲಾಗಿದೆ"
+
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 9a31649be3..e73ff39da0 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"
"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"
"ಅಧಿಸೂಚನೆಗಳು"
+ "ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ."
+ "ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ."
"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."
"ಮೆಚ್ಚಿನವುಗಳ ಟ್ರೇನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"
"ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"
+ "ವೈಯಕ್ತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"
+ "ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿ"
"ಮುಖಪುಟ"
"ತೆಗೆದುಹಾಕಿ"
- "ಅಸ್ಥಾಪಿಸು"
+ "ಅನ್ಇನ್ಸ್ಟಾಲ್"
"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"
+ "ಸ್ಥಾಪಿಸಿ"
"ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"
"ಬಳಕೆದಾರರ ಹಸ್ತಕ್ಷೇಪವಿಲ್ಲದೆ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."
"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಓದಿ"
@@ -59,6 +64,10 @@
"ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."
"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"
"%1$s ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"
+
+ - %1$s, %2$d ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ
+ - %1$s, %2$d ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ
+
"%2$d ರಲ್ಲಿ %1$d ಪುಟ"
"%2$d ರಲ್ಲಿ %1$d ಮುಖಪುಟದ ಪರದೆ"
"ಹೊಸ ಮುಖಪುಟ ಪರದೆ"
@@ -72,19 +81,19 @@
"ವಾಲ್ಪೇಪರ್ಗಳು"
"ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್ಗಳು"
"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"
- "ಅವಲೋಕನ"
"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"
"ಫೋನ್ ತಿರುಗಿಸಿದಾಗ"
- "ಪ್ರಸ್ತುತ ಪ್ರದರ್ಶನ ಸೆಟ್ಟಿಂಗ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"
"ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳು"
"ಆನ್"
"ಆಫ್"
"ಅಧಿಸೂಚನೆ ಪ್ರವೇಶ ಅಗತ್ಯವಿದೆ"
"ಅಧಿಸೂಚನೆ ಚುಕ್ಕೆಗಳನ್ನು ತೋರಿಸಲು, %1$s ಗೆ ಅಪ್ಲಿಕೇಶನ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್ ಮಾಡಿ"
"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"
+ "ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳನ್ನು ತೋರಿಸಿ"
"ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"
"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ"
"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"
+ "ಮುಖಪುಟ ಪರದೆಯಲ್ಲಿ"
"ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ"
"ಚೌಕ"
"ಚೌಕವೃತ್ತ"
@@ -99,6 +108,10 @@
"%1$s ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ, %2$s ಪೂರ್ಣಗೊಂಡಿದೆ"
"%1$s ಸ್ಥಾಪಿಸಲು ಕಾಯಲಾಗುತ್ತಿದೆ"
"%1$s ವಿಜೆಟ್ಗಳು"
+
+
+
+
"ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸು"
"ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ"
"ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"
@@ -114,9 +127,6 @@
"ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಫೋಲ್ಡರ್ ರಚಿಸಿ: %1$s"
"ಫೋಲ್ಡರ್ ರಚಿಸಲಾಗಿದೆ"
"ಮುಖಪುಟಕ್ಕೆ ಸರಿಸಿ"
- "ಪರದೆಯನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ"
- "ಪರದೆಯನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ"
- "ಪರದೆ ಸರಿಸಲಾಗಿದೆ"
"ಮರುಗಾತ್ರ"
"ಅಗಲವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"
"ಎತ್ತರವನ್ನು ಹೆಚ್ಚು ಮಾಡಿ"
@@ -124,8 +134,16 @@
"ಎತ್ತರವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"
"ವಿಜೆಟ್ ಅನ್ನು %1$s ಅಗಲ %2$s ಎತ್ತರಕ್ಕೆ ಮರುಗಾತ್ರಗೊಳಿಸಲಾಗಿದೆ"
"ಶಾರ್ಟ್ಕಟ್ಗಳು"
- "%2$s ಗೆ %1$d ಶಾರ್ಟ್ಕಟ್ಗಳು"
- "%3$s ಗಾಗಿ %1$d ಶಾರ್ಟ್ಕಟ್ಗಳು ಮತ್ತು %2$d ಅಧಿಸೂಚನೆಗಳು"
+ "ಶಾರ್ಟ್ಕಟ್ಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳು"
"ವಜಾಗೊಳಿಸಿ"
"ಅಧಿಸೂಚನೆಯನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ"
+ "ವೈಯಕ್ತಿಕ"
+ "ಕೆಲಸ"
+ "ಕೆಲಸದ ಪ್ರೊಫೈಲ್"
+ "ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಇಲ್ಲಿ ಹುಡುಕಿ"
+ "ಕೆಲಸದ ಪ್ರತಿ ಅಪ್ಲಿಕೇಶನ್ ಬ್ಯಾಡ್ಜ್ ಹೊಂದಿದೆ ಮತ್ತು ನಿಮ್ಮ ಸಂಸ್ಥೆಯಿಂದ ಸುರಕ್ಷಿತವಾಗಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಸುಲಭ ಪ್ರವೇಶಕ್ಕಾಗಿ ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸರಿಸಿ."
+ "ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ"
+ "ಅಧಿಸೂಚನೆಗಳು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್ಗಳು ಆಫ್ ಆಗಿವೆ"
+ "ಮುಚ್ಚಿ"
+ "ಮುಚ್ಚಲಾಗಿದೆ"
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index e3511d4413..5e68b1733e 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -40,13 +40,18 @@
"\'%1$s\'과(와) 일치하는 앱이 없습니다."
"더 많은 앱 검색"
"알림"
+ "바로가기를 선택하려면 길게 터치하세요."
+ "바로가기를 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 동작을 사용하세요."
"홈 화면에 더 이상 공간이 없습니다."
"즐겨찾기 트레이에 더 이상 공간이 없습니다."
"앱 목록"
+ "개인 앱 목록"
+ "업무용 앱 목록"
"홈"
"삭제"
"제거"
"앱 정보"
+ "설치"
"바로가기 설치"
"앱이 사용자의 작업 없이 바로가기를 추가할 수 있도록 합니다."
"홈 설정 및 바로가기 읽기"
@@ -59,6 +64,10 @@
"시스템 앱은 제거할 수 없습니다."
"이름이 없는 폴더"
"%1$s 사용 안함"
+
+ - %2$d개의 %1$s 알림 있음
+ - %2$d개의 %1$s 알림 있음
+
"페이지 %1$d/%2$d"
"홈 화면 %1$d/%2$d"
"새로운 홈 화면 페이지"
@@ -72,19 +81,19 @@
"배경화면"
"홈 설정"
"관리자가 사용 중지함"
- "개요"
"홈 화면 회전 허용"
"휴대전화 회전 시"
- "현재 표시 설정에는 회전 기능이 허용되지 않습니다."
"알림 표시 점"
"사용"
"사용 안함"
"알림 액세스 권한 필요"
"알림 표시점을 표시하려면 %1$s의 앱 알림을 사용 설정하세요."
"설정 변경"
+ "알림 표시 점 보기"
"홈 화면에 아이콘 추가"
"새로 설치한 앱에 적용"
"아이콘 모양 변경"
+ "홈 화면에 표시"
"시스템 기본값 사용"
"정사각형"
"모서리가 둥근 정사각형"
@@ -99,6 +108,8 @@
"%1$s 다운로드 중, %2$s 완료"
"%1$s 설치 대기 중"
"%1$s 위젯"
+ "위젯 목록"
+ "위젯 목록 닫힘"
"홈 화면에 추가"
"여기에 항목을 이동"
"홈 화면에 항목 추가됨"
@@ -114,9 +125,6 @@
"다음이 포함된 폴더 만들기: %1$s"
"폴더를 만들었습니다."
"홈 화면으로 이동"
- "화면을 왼쪽으로 이동"
- "화면을 오른쪽으로 이동"
- "화면 이동됨"
"크기 조정"
"폭 늘리기"
"높이 늘리기"
@@ -124,8 +132,16 @@
"높이 줄이기"
"폭 %1$s, 높이 %2$s로 위젯 크기 조정됨"
"바로가기"
- "%2$s에 사용 가능한 단축키 %1$d개"
- "바로가기 %1$d개 및 %3$s 알림 %2$d개"
+ "바로가기 및 알림"
"닫기"
"알림이 해제되었습니다."
+ "개인"
+ "직장"
+ "직장 프로필"
+ "여기에서 업무용 앱 찾기"
+ "각 업무용 앱에는 배지가 있으며 업무용 앱은 조직에서 안전하게 보호됩니다. 앱을 홈 화면으로 이동하여 더 간편하게 사용하세요."
+ "조직에서 관리"
+ "알림 및 앱 사용 중지됨"
+ "닫기"
+ "종료됨"
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
new file mode 100644
index 0000000000..502a08a3e1
--- /dev/null
+++ b/res/values-ky-rKG/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Жумуш"
+ "Колдонмо орнотулган эмес."
+ "Колдонмо жеткиликтүү эмес"
+ "Жүктөп алынган колдонмо Коопсуз режиминде иштен чыгарылды"
+ "Виджеттер Коопсуз режимде өчүрүлгөн"
+ "Кыска жол жок"
+ "Башкы экран"
+ "Ыңгайлаштырылган аракеттер"
+ "Виджетти тандаш үчүн, басып туруңуз"
+ "Виджет тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."
+ "%1$d × %2$d"
+ "Туурасы: %1$d, бийиктиги: %2$d"
+ "Кол менен жайгаштыруу үчүн басып туруп, таштаңыз"
+ "Автоматтык түрдө кошуу"
+ "Колдонмолорду издөө"
+ "Колдонмолор жүктөлүүдө…"
+ "\"%1$s\" сурамына дал келген колдонмолор табылган жок"
+ "Көбүрөөк колдонмолорду издөө"
+ "Билдирмелер"
+ "Кыска жолду тандоо үчүн басып туруңуз."
+ "Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."
+ "Бул Үй экранында бош орун жок."
+ "Тандамалдар тайпасында орун калган жок"
+ "Колдонмолор тизмеси"
+ "Жеке колдономолордун тизмеси"
+ "Жумуш колдонмолорунун тизмеси"
+ "Үйгө"
+ "Алып салуу"
+ "Чыгарып салуу"
+ "Колдонмо тууралуу"
+ "Орнотуу"
+ "тез чакырмаларды орнотуу"
+ "Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."
+ "Үйдүн тууралоолорун жана тез чакырмаларын окуу"
+ "Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын окууга уруксат берет."
+ "Үйдүн тууралоолорун жана тез чакырмаларын жазуу"
+ "Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын өзгөртүүгө уруксат берет."
+ "%1$s телефон чалууларды аткарууга уруксаты жок"
+ "Виджетти жүктөөдө маселе бар"
+ "Орнотуу"
+ "Бул системдик колдонмо жана аны чечкенге болбойт."
+ "Аты жок фолдер"
+ "%1$s өчүрүлгөн"
+
+ - %1$s, %2$d эскертме бар
+ - %1$s, %2$d эскертме бар
+
+ "%2$d ичинен %1$d барак"
+ "Үй экраны %2$d ичинен %1$d"
+ "Жаңы башкы экран барагы"
+ "Фолдер ачылды, туурасы %1$d, бийиктиги %2$d"
+ "Куржунду жабуу үчүн таптаңыз"
+ "Өзгөртүлгөн аталышын сактоо үчүн таптаңыз"
+ "Фолдер жабык"
+ "Фолдердин аты %1$s деп өзгөртүлдү"
+ "Фолдер: %1$s"
+ "Виджеттер"
+ "Тушкагаздар"
+ "Башкы беттин жөндөөлөрү"
+ "Администраторуңуз өчүрүп койгон"
+ "Башкы экранды айлантууга уруксат берүү"
+ "Телефон айланганда"
+ "Билдирмелер белгилери"
+ "Күйүк"
+ "Өчүк"
+ "Эскертмелерге уруксат берилиши керек"
+ "Эскертме белгилерин көрсөтүү максатында, %1$s үчүн колдонмонун эскертмелерин күйгүзүү керек"
+ "Жөндөөлөрдү өзгөртүү"
+ "Эскертме белгилерин көрсөтүү"
+ "Башкы экранга сүрөтчө кошуу"
+ "Жаңы колдонмолор үчүн"
+ "Сүрөтчөнүн формасын өзгөртүү"
+ "Башкы экранда"
+ "Демейки тутум жөндөөлөрү колдонулат"
+ "Чарчы"
+ "Бурчтары жумуру төрт бурчтук"
+ "Тегерек"
+ "Тамчы"
+ "Өзгөртүлгөн сүрөтчөнүн формасы колдонулууда"
+ "Белгисиз"
+ "Алып салуу"
+ "Издөө"
+ "Бул колдонмо орнотулган эмес"
+ "Бул сүрөтчөнүн колдонмосу орнотулган эмес. Аны алып салсаңыз же колдонмону издеп, кол менен орнотсоңуз болот."
+ "%1$s жүктөлүп алынууда, %2$s аяктады"
+ "%1$s орнотулушу күтүлүүдө"
+ "%1$s виджеттери"
+ "Башкы экранга кошуу"
+ "Бул нерсени бул жерге жылдыруу"
+ "Башкы экранга кошулду"
+ "Жоюлду"
+ "Муну жылдыруу"
+ "%1$s катарга %2$s тилкеге жылдыруу"
+ "%1$s орунга жылдыруу"
+ "Сүйүктүүлөргө %1$s жылдыруу"
+ "Нерсе жылдырылды"
+ "Куржунга кошуу: %1$s"
+ "%1$s куржунуна кошуу"
+ "Нерсе куржунга кошулду"
+ "Төмөнкү менен куржун түзүү: %1$s"
+ "Куржун түзүлдү"
+ "Башкы экранга жылдыруу"
+ "Өлчөмүн өзгөртүү"
+ "Кеңейтүү"
+ "Бийиктетүү"
+ "Ичкертүү"
+ "Жапыздатуу"
+ "Виджеттин кеңдиги %1$s бийиктиги %2$s болду"
+ "Кыска жолдор"
+ "%2$s колдонмосуна %1$d кыска жол бар"
+ "%3$s колдонмосу үчүн %1$d кыска жол жана %2$d эскертме бар"
+ "Этибарга албоо"
+ "Эскертме көз жаздымда калтырылды"
+ "Жеке колдонмолор"
+ "Жумуш колдонмолору"
+ "Жумуш профили"
+ "Жумуш колдонмолорун бул жерден таап алыңыз"
+ "Ар бир жумуш колдонмосунун бейджиги бар жана ал уюмуңуз тарабынан коопсуз сакталат. Колдонмолорго тез өтүү үчүн аларды Башкы экранга кошуп алыңыз."
+ "Уюмуңуз тарабынан башкарылат"
+ "Билдирүүлөр жана колдонмолор өчүрүлгөн"
+ "Жабуу"
+ "Жабык"
+
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 85ba8be3c3..da7813e741 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -39,14 +39,19 @@
"Колдонмолор жүктөлүүдө…"
"\"%1$s\" сурамына дал келген колдонмолор табылган жок"
"Көбүрөөк колдонмолорду издөө"
- "Эскертмелер"
+ "Билдирмелер"
+ "Кыска жолду тандоо үчүн басып туруңуз."
+ "Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."
"Бул Үй экранында бош орун жок."
"Тандамалдар тайпасында орун калган жок"
"Колдонмолор тизмеси"
+ "Жеке колдономолордун тизмеси"
+ "Жумуш колдонмолорунун тизмеси"
"Үйгө"
"Алып салуу"
"Чыгарып салуу"
"Колдонмо тууралуу"
+ "Орнотуу"
"тез чакырмаларды орнотуу"
"Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."
"Үйдүн тууралоолорун жана тез чакырмаларын окуу"
@@ -59,6 +64,10 @@
"Бул системдик колдонмо жана аны чечкенге болбойт."
"Аты жок фолдер"
"%1$s өчүрүлгөн"
+
+ - %1$s, %2$d эскертме бар
+ - %1$s, %2$d эскертме бар
+
"%2$d ичинен %1$d барак"
"Үй экраны %2$d ичинен %1$d"
"Жаңы башкы экран барагы"
@@ -72,20 +81,20 @@
"Тушкагаздар"
"Башкы беттин жөндөөлөрү"
"Администраторуңуз өчүрүп койгон"
- "Көз жүгүртүү"
"Башкы экранды айлантууга уруксат берүү"
"Телефон айланганда"
- "Экранды айлантуу параметри өчүрүлгөн"
- "Эскертме белгилери"
+ "Билдирмелер белгилери"
"Күйүк"
"Өчүк"
"Эскертмелерге уруксат берилиши керек"
"Эскертме белгилерин көрсөтүү максатында, %1$s үчүн колдонмонун эскертмелерин күйгүзүү керек"
"Жөндөөлөрдү өзгөртүү"
+ "Эскертме белгилерин көрсөтүү"
"Башкы экранга сүрөтчө кошуу"
"Жаңы колдонмолор үчүн"
"Сүрөтчөнүн формасын өзгөртүү"
- "Тутум сушунтаган демейкисин колдонуу"
+ "Башкы экранда"
+ "Демейки тутум жөндөөлөрү колдонулат"
"Чарчы"
"Бурчтары жумуру төрт бурчтук"
"Тегерек"
@@ -99,6 +108,8 @@
"%1$s жүктөлүп алынууда, %2$s аяктады"
"%1$s орнотулушу күтүлүүдө"
"%1$s виджеттери"
+ "Виджеттердин тизмеси"
+ "Виджеттердин тизмеси жабык"
"Башкы экранга кошуу"
"Бул нерсени бул жерге жылдыруу"
"Башкы экранга кошулду"
@@ -114,9 +125,6 @@
"Төмөнкү менен куржун түзүү: %1$s"
"Куржун түзүлдү"
"Башкы экранга жылдыруу"
- "Экранды солго жылдыруу"
- "Экранды оңго жылдыруу"
- "Экран жылдырылды"
"Өлчөмүн өзгөртүү"
"Кеңейтүү"
"Бийиктетүү"
@@ -124,8 +132,16 @@
"Жапыздатуу"
"Виджеттин кеңдиги %1$s бийиктиги %2$s болду"
"Кыска жолдор"
- "%2$s колдонмосуна %1$d кыска жол бар"
- "%3$s колдонмосу үчүн %1$d кыска жол жана %2$d эскертме бар"
+ "Кыска жолдор жана билдирмелер"
"Этибарга албоо"
"Эскертме көз жаздымда калтырылды"
+ "Жеке колдонмолор"
+ "Жумуш колдонмолору"
+ "Жумуш профили"
+ "Жумуш колдонмолорун бул жерден таап алыңыз"
+ "Ар бир жумуш колдонмосунун бейджиги бар жана ал уюмуңуз тарабынан коопсуз сакталат. Колдонмолорго тез өтүү үчүн аларды Башкы экранга кошуп алыңыз."
+ "Уюмуңуз тарабынан башкарылат"
+ "Билдирүүлөр жана колдонмолор өчүрүлгөн"
+ "Жабуу"
+ "Жабык"
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 92420a2f12..f0021956a1 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -25,29 +25,13 @@
24dp
- 120dp
- 48dp
4dp
0dp
5.5dp
-
- 2dp
-
-
- 50dp
- 74dp
-
0dp
-
- 50dp
- 44dp
- 18dp
-
- 56dp
- 32dp
- 6dp
+ 16dp
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000000..cd2c933c15
--- /dev/null
+++ b/res/values-lo-rLA/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "ວຽກ"
+ "ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."
+ "ແອັບຯໃຊ້ບໍ່ໄດ້"
+ "ແອັບຯທີ່ດາວໂຫລດແລ້ວຖືກປິດການນຳໃຊ້ໃນ Safe mode"
+ "ວິດເຈັດຖືກປິດໃນ Safe mode"
+ "ບໍ່ສາມາດໃຊ້ທາງລັດໄດ້"
+ "ໜ້າຈໍຫຼັກ"
+ "ຄຳສັ່ງແບບກຳນົດເອງ"
+ "ສຳພັດຄ້າງໄວ້ ເພື່ອຈັບວິດເຈັດ."
+ "ແຕະຄ້າງໄວ້ ເພື່ອເລືອກວິດເຈັດ ຫຼື ໃຊ້ການດຳເນີນການກຳນົດເອງ."
+ "%1$d × %2$d"
+ "ກວ້າງ %1$d ຄູນສູງ %2$d"
+ "ແຕະຄ້າງໄວ້ເພື່ອວາງດ້ວຍຕົນເອງ"
+ "ເພີ່ມໂດຍອັດຕະໂນມັດ"
+ "ຊອກຫາແອັບ"
+ "ກໍາລັງໂຫຼດແອັບ…"
+ "ບໍ່ພົບແອັບທີ່ກົງກັບ \"%1$s\""
+ "ຊອກຫາແອັບເພີ່ມເຕີມ"
+ "ການແຈ້ງເຕືອນ"
+ "ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."
+ "ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."
+ "ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."
+ "ບໍ່ມີບ່ອນຫວ່າງໃນຖາດສຳລັບເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"
+ "ລາຍຊື່ແອັບ"
+ "ລາຍຊື່ແອັບສ່ວນຕົວ"
+ "ລາຍຊື່ແອັບເຮັດວຽກ"
+ "ໜ້າຫຼັກ"
+ "ເອົາອອກ"
+ "ຖອນການຕິດຕັ້ງ"
+ "ຂໍ້ມູນແອັບ"
+ "ຕິດຕັ້ງ"
+ "ຕິດຕັ້ງທາງລັດ"
+ "ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມທາງລັດໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."
+ "ອ່ານການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"
+ "ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວອ່ານການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."
+ "ຂຽນການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"
+ "ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ປ່ຽນການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."
+ "%1$s ບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ໂທ"
+ "ມີບັນຫາໃນການໂຫລດວິດເຈັດ"
+ "ຕິດຕັ້ງ"
+ "ນີ້ແມ່ນແອັບຯຂອງລະບົບ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງອອກໄດ້."
+ "ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"
+ "ປິດການນຳໃຊ້ %1$s ແລ້ວ"
+
+ - %1$s, ມີ %2$d ການແຈ້ງເຕືອນ
+ - %1$s, ມີ %2$d ການແຈ້ງເຕືອນ
+
+ "ໜ້າ %1$d ຈາກ %2$d"
+ "ໜ້າຈໍຫຼັກ %1$d ໃນ %2$d"
+ "ໜ້າຂອງໜ້າຈໍຫຼັກໃໝ່"
+ "ເປີດໂຟນເດີແລ້ວ, %1$d ຄູນ %2$d"
+ "ແຕະເພື່ອປິດໂຟນເດີ"
+ "ແຕະເພື່ອບັນທຶກການປ່ຽນຊື່"
+ "ປິດໂຟນເດີແລ້ວ"
+ "ປ່ຽນຊື່ໂຟນເດີເປັນ %1$s ແລ້ວ"
+ "ໂຟນເດີ: %1$s"
+ "ວິດເຈັດ"
+ "ພາບພື້ນຫຼັງ"
+ "ການຕັ້ງຄ່າ Home"
+ "ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"
+ "ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"
+ "ເມື່ອໝຸນໂທລະສັບ"
+ "ຈຸດການແຈ້ງເຕືອນ"
+ "ເປີດ"
+ "ປິດ"
+ "ຕ້ອງໃຊ້ການເຂົ້າເຖິງການແຈ້ງເຕືອນ"
+ "ເພື່ອສະແດງຈຸດການແຈ້ງເຕືອນ, ໃຫ້ເປີດການແຈ້ງເຕືອນສຳລັບ %1$s"
+ "ບັນທຶກການຕັ້ງຄ່າ"
+ "ສະແດງຈຸດການແຈ້ງເຕືອນ"
+ "ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"
+ "ສຳລັບແອັບໃໝ່"
+ "ປ່ຽນຮູບຮ່າງໄອຄອນ"
+ "ຢູ່ໜ້າຈໍຫຼັກ"
+ "ໃຊ້ຄ່າເລີ່ມຕົ້ນລະບົບ"
+ "ສີ່ຫຼ່ຽມຈັດຕຸລັດ"
+ "ສີ່ຫຼ່ຽມຂອບມົນ"
+ "ວົງມົນ"
+ "ນ້ຳຢອດ"
+ "ນຳໃຊ້ການປ່ຽນແປງຮູບຮ່າງໄອຄອນ"
+ "ບໍ່ຮູ້ຈັກ"
+ "ລຶບ"
+ "ຊອກຫາ"
+ "ແອັບຯນີ້ຍັງບໍ່ໄດ້ຕິດຕັ້ງເທື່ອ"
+ "ແອັບຯສຳລັບໄອຄອນນີ້ຍັງບໍ່ໄດ້ຕິດຕັ້ງເທື່ອ. ທ່ານສາມາດລຶບມັນອອກ ຫຼືຊອກຫາແອັບຯ ແລ້ວຕິດຕັ້ງມັນໄດ້ດ້ວຍຕົນເອງ."
+ "%1$s ກຳລັງດາວໂຫຼດ, %2$s ສຳເລັດ"
+ "%1$s ກຳລັງລໍຖ້າຕິດຕັ້ງ"
+ "ວິດເຈັດ %1$s"
+ "ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"
+ "Move item here"
+ "ເພີ່ມລາຍການໃສ່ໜ້າຈໍຫຼັກແລ້ວ"
+ "ເອົາລາຍການອອກໄປແລ້ວ"
+ "ຍ້າຍລາຍການ"
+ "ຍ້າຍໄປໃສ່ແຖວ %1$s ຖັນ %2$s"
+ "ຍ້າຍໄປໃສ່ຕຳແໜ່ງ %1$s"
+ "ຍ້າຍໄປໃສ່ຕຳແໜ່ງທີ່ມັກ %1$s"
+ "ຍ້າຍລາຍການແລ້ວ"
+ "ເພີ່ມໃສ່ໂຟລເດີ: %1$s"
+ "ເພີ່ມໃສ່ໂຟລເດີດ້ວຍ %1$s"
+ "ເພີ່ມລາຍການໃສ່ໂຟລເດີແລ້ວ"
+ "ສ້າງໂຟລເດີກັບ: %1$s"
+ "ສ້າງໂຟລເດີແລ້ວ"
+ "ຍ້າຍໄປໃສ່ໜ້າຈໍຫຼັກ"
+ "ປັບຂະໜາດ"
+ "ເພີ່ມລວງກ້ວາງຂຶ້ນ"
+ "ເພີ່ມລວງສູງຂຶ້ນ"
+ "ຫຼຸດລວງກ້ວາງລົງ"
+ "ຫຼຸດລວງສູງລົງ"
+ "ປ່ຽນຂະໜາດວິດເຈັດເປັນລວງກ້ວາງ %1$s ລວງສູງ %2$s ແລ້ວ"
+ "ທາງລັດ"
+ "%1$d ທາງລັດສຳລັບ %2$s"
+ "%1$d ທາງລັດ ແລະ %2$d ການແຈ້ງເຕືອນສຳລັບ %3$s"
+ "ປິດໄວ້"
+ "ປິດການແຈ້ງເຕືອນແລ້ວ"
+ "ສ່ວນຕົວ"
+ "ວຽກ"
+ "ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"
+ "ຊອກຫາແອັບວຽກຢູ່ບ່ອນນີ້"
+ "ແຕ່ລະແອັບວຽກຈະມີປ້າຍ ແລະ ຖືກຈັດເກັບໄວ້ຢ່າງປອດໄພໂດຍອົງກອນຂອງທ່ານ. ທ່ານສາມາດຍ້າຍແອັບໄປໃສ່ໜ້າຈໍຫຼັກເພື່ອໃຫ້ເຂົ້າໃຊ້ງ່າຍຂຶ້ນໄດ້."
+ "ຈັດການໂດຍອົງກອນຂອງທ່ານ"
+ "ການແຈ້ງເຕືອນ ແລະ ແອັບຖືກປິດໄວ້"
+ "ປິດ"
+ "ປິດແລ້ວ"
+
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 9a50c4b517..d0d127f996 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -40,13 +40,18 @@
"ບໍ່ພົບແອັບທີ່ກົງກັບ \"%1$s\""
"ຊອກຫາແອັບເພີ່ມເຕີມ"
"ການແຈ້ງເຕືອນ"
+ "ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."
+ "ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."
"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."
"ບໍ່ມີບ່ອນຫວ່າງໃນຖາດສຳລັບເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"
"ລາຍຊື່ແອັບ"
+ "ລາຍຊື່ແອັບສ່ວນຕົວ"
+ "ລາຍຊື່ແອັບເຮັດວຽກ"
"ໜ້າຫຼັກ"
"ເອົາອອກ"
"ຖອນການຕິດຕັ້ງ"
"ຂໍ້ມູນແອັບ"
+ "ຕິດຕັ້ງ"
"ຕິດຕັ້ງທາງລັດ"
"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມທາງລັດໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."
"ອ່ານການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"
@@ -59,6 +64,10 @@
"ນີ້ແມ່ນແອັບຯຂອງລະບົບ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງອອກໄດ້."
"ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"
"ປິດການນຳໃຊ້ %1$s ແລ້ວ"
+
+ - %1$s, ມີ %2$d ການແຈ້ງເຕືອນ
+ - %1$s, ມີ %2$d ການແຈ້ງເຕືອນ
+
"ໜ້າ %1$d ຈາກ %2$d"
"ໜ້າຈໍຫຼັກ %1$d ໃນ %2$d"
"ໜ້າຂອງໜ້າຈໍຫຼັກໃໝ່"
@@ -72,19 +81,19 @@
"ພາບພື້ນຫຼັງ"
"ການຕັ້ງຄ່າ Home"
"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"
- "ພາບຮວມ"
"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"
"ເມື່ອໝຸນໂທລະສັບ"
- "ການຕັ້ງຄ່າສະແດງຜົນປັດຈຸບັນບໍ່ອະນຸຍາດໃຫ້ໝຸນໄດ້"
"ຈຸດການແຈ້ງເຕືອນ"
"ເປີດ"
"ປິດ"
"ຕ້ອງໃຊ້ການເຂົ້າເຖິງການແຈ້ງເຕືອນ"
"ເພື່ອສະແດງຈຸດການແຈ້ງເຕືອນ, ໃຫ້ເປີດການແຈ້ງເຕືອນສຳລັບ %1$s"
"ບັນທຶກການຕັ້ງຄ່າ"
+ "ສະແດງຈຸດການແຈ້ງເຕືອນ"
"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"
"ສຳລັບແອັບໃໝ່"
"ປ່ຽນຮູບຮ່າງໄອຄອນ"
+ "ຢູ່ໜ້າຈໍຫຼັກ"
"ໃຊ້ຄ່າເລີ່ມຕົ້ນລະບົບ"
"ສີ່ຫຼ່ຽມຈັດຕຸລັດ"
"ສີ່ຫຼ່ຽມຂອບມົນ"
@@ -99,6 +108,8 @@
"%1$s ກຳລັງດາວໂຫຼດ, %2$s ສຳເລັດ"
"%1$s ກຳລັງລໍຖ້າຕິດຕັ້ງ"
"ວິດເຈັດ %1$s"
+ "ລາຍຊື່ວິດເຈັດ"
+ "ປິດລາຍຊື່ວິດເຈັດແລ້ວ"
"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"
"Move item here"
"ເພີ່ມລາຍການໃສ່ໜ້າຈໍຫຼັກແລ້ວ"
@@ -114,9 +125,6 @@
"ສ້າງໂຟລເດີກັບ: %1$s"
"ສ້າງໂຟລເດີແລ້ວ"
"ຍ້າຍໄປໃສ່ໜ້າຈໍຫຼັກ"
- "ຍ້າຍໜ້າຈໍໄປທາງຊ້າຍ"
- "ຍ້າຍໜ້າຈໍໄປທາງຂວາ"
- "ຍ້າຍໜ້າຈໍແລ້ວ"
"ປັບຂະໜາດ"
"ເພີ່ມລວງກ້ວາງຂຶ້ນ"
"ເພີ່ມລວງສູງຂຶ້ນ"
@@ -124,8 +132,16 @@
"ຫຼຸດລວງສູງລົງ"
"ປ່ຽນຂະໜາດວິດເຈັດເປັນລວງກ້ວາງ %1$s ລວງສູງ %2$s ແລ້ວ"
"ທາງລັດ"
- "%1$d ທາງລັດສຳລັບ %2$s"
- "%1$d ທາງລັດ ແລະ %2$d ການແຈ້ງເຕືອນສຳລັບ %3$s"
+ "ປຸ່ມລັດ ແລະ ການແຈ້ງເຕືອນ"
"ປິດໄວ້"
"ປິດການແຈ້ງເຕືອນແລ້ວ"
+ "ສ່ວນຕົວ"
+ "ວຽກ"
+ "ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"
+ "ຊອກຫາແອັບວຽກຢູ່ບ່ອນນີ້"
+ "ແຕ່ລະແອັບວຽກຈະມີປ້າຍ ແລະ ຖືກຈັດເກັບໄວ້ຢ່າງປອດໄພໂດຍອົງກອນຂອງທ່ານ. ທ່ານສາມາດຍ້າຍແອັບໄປໃສ່ໜ້າຈໍຫຼັກເພື່ອໃຫ້ເຂົ້າໃຊ້ງ່າຍຂຶ້ນໄດ້."
+ "ຈັດການໂດຍອົງກອນຂອງທ່ານ"
+ "ການແຈ້ງເຕືອນ ແລະ ແອັບຖືກປິດໄວ້"
+ "ປິດ"
+ "ປິດແລ້ວ"
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index d415e4df1b..c323fd838f 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -40,13 +40,18 @@
"Nerasta jokių užklausą „%1$s“ atitinkančių programų"
"Ieškoti daugiau programų"
"Pranešimai"
+ "Paliesk. ir palaikyk., kad pasirinkt. spart. klav."
+ "Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus."
"Šiame pagrindiniame ekrane vietos nebėra."
"Mėgstamiausių dėkle nebėra vietos"
"Programų sąrašas"
+ "Asmeninių programų sąrašas"
+ "Darbo programų sąrašas"
"Pagrindinis"
"Ištrinti"
"Pašalinti"
"Programos inform."
+ "Įdiegti"
"įdiegti sparčiuosius klavišus"
"Programai leidžiama pridėti sparčiuosius klavišus be naudotojo įsikišimo."
"skaityti pagrindinio puslapio nustatymus ir sparčiuosius klavišus"
@@ -59,6 +64,12 @@
"Tai sistemos programa ir jos negalima pašalinti."
"Aplankas be pavadinimo"
"„%1$s“ išjungta"
+
+ - „%1$s“, yra %2$d pranešimas
+ - „%1$s“, yra %2$d pranešimai
+ - „%1$s“, yra %2$d pranešimo
+ - „%1$s“, yra %2$d pranešimų
+
"%1$d psl. iš %2$d"
"%1$d pagrindinis ekranas iš %2$d"
"Naujas pagrindinio ekrano puslapis"
@@ -72,19 +83,19 @@
"Ekrano fonai"
"„Home“ nustatymai"
"Išjungė administratorius"
- "Apžvalga"
"Leisti pasukti pagrindinį ekraną"
"Kai telefonas pasukamas"
- "Naudojant dabartinį pateikties nustatymą neleidžiama pasukti"
"Pranešimų taškai"
"Įjungta"
"Išjungta"
"Reikalinga prieiga prie pranešimų"
"Kad būtų rodomi pranešimų taškai, įjunkite programos „%1$s“ pranešimus."
"Keisti nustatymus"
+ "Rodyti pranešimų taškus"
"Pridėti piktogr. prie pagrindinio ekrano"
"Skirta naujoms programoms"
"Pakeisti piktogramos formą"
+ "pagrindiniame ekrane"
"Naudoti numatytuosius sistemos nustatymus"
"Kvadratas"
"Kvadratais suapvalintais kampais"
@@ -99,6 +110,8 @@
"Atsisiunčiama programa „%1$s“, %2$s baigta"
"Laukiama, kol bus įdiegta programa „%1$s“"
"„%1$s“ valdikliai"
+ "Valdiklių sąrašas"
+ "Valdiklių sąrašas uždarytas"
"Pridėti prie pagrind. ekrano"
"Perkelti elementą čia"
"Elementas pridėtas prie pagrindinio ekrano"
@@ -114,9 +127,6 @@
"Kurti aplanką naudojant: „%1$s“"
"Aplankas sukurtas"
"Perkelti į pagrindinį ekraną"
- "Perkelti ekraną į kairę"
- "Perkelti ekraną į dešinę"
- "Ekranas perkeltas"
"Pakeisti dydį"
"Padidinti plotį"
"Padidinti aukštį"
@@ -124,8 +134,16 @@
"Sumažinti aukštį"
"Valdiklio dydis pakeistas: plotis – %1$s, aukštis – %2$s"
"Spartieji klavišai"
- "Programos „%2$s“ spartieji klavišai (%1$d)"
- "„%3$s“ spartieji klavišai (%1$d) ir pranešimai (%2$d)"
+ "Spartieji klavišai ir pranešimai"
"Atsisakyti"
"Pranešimo atsisakyta"
+ "Asmeninės"
+ "Darbo"
+ "Darbo profilis"
+ "Darbo programas rasite čia"
+ "Kiekvienai darbo programai priskirtas ženklelis, o tokių programų sauga rūpinasi jūsų organizacija. Perkelkite programas į pagrindinį ekraną, kad galėtumėte lengviau jas pasiekti."
+ "Tvarko jūsų organizacija"
+ "Programos ir pranešimai išjungti"
+ "Uždaryti"
+ "Uždaryta"
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 2d8bfd83a3..be03811c9a 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -40,13 +40,18 @@
"Vaicājumam “%1$s” neatbilda neviena lietotne"
"Meklēt citas lietotnes"
"Paziņojumi"
+ "Lai atlasītu saīsni, pieskarieties un turiet to."
+ "Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to. Varat arī veikt pielāgotas darbības."
"Šajā sākuma ekrānā vairs nav vietas."
"Izlases joslā vairs nav vietas."
"Lietotņu saraksts"
+ "Personīgo lietotņu saraksts"
+ "Darba lietotņu saraksts"
"Sākums"
"Noņemt"
"Atinstalēt"
- "Lietotnes informācija"
+ "Par lietotni"
+ "Instalēt"
"instalēt saīsnes"
"Ļauj lietotnei pievienot saīsnes, nejautājot lietotājam."
"lasīt sākuma ekrāna iestatījumus un saīsnes"
@@ -59,6 +64,11 @@
"Šī ir sistēmas lietotne, un to nevar atinstalēt."
"Mape bez nosaukuma"
"Lietotne %1$s ir atspējota"
+
+ - %1$s, ir %2$d paziņojumi
+ - %1$s, ir %2$d paziņojums
+ - %1$s, ir %2$d paziņojumi
+
"%1$d. lapa no %2$d"
"Sākuma ekrāns: %1$d no %2$d"
"Jauna sākuma ekrāna lapa"
@@ -72,19 +82,19 @@
"Fona tapetes"
"Sākumlapas iestatījumi"
"Atspējojis administrators"
- "Kopsavilkums"
"Atļaut sākuma ekrāna pagriešanu"
"Pagriežot tālruni"
- "Pašreizējā displeja iestatījumā nav atļauta pagriešana."
"Paziņojumu punkti"
"Ieslēgts"
"Izslēgts"
"Nepieciešama piekļuve paziņojumiem"
"Lai tiktu rādīti paziņojumu punkti, ieslēdziet paziņojumus lietotnei %1$s."
"Mainīt iestatījumus"
+ "Rādīt paziņojumu punktus"
"Pievienot ikonu sākuma ekrānā"
"Jaunām lietotnēm"
"Mainīt ikonu formu"
+ "sākuma ekrānā"
"Izmantot sistēmas noklusējumu"
"Kvadrāts"
"Kvadrāts ar noapaļotiem stūriem"
@@ -99,6 +109,8 @@
"Lietotnes %1$s lejupielāde (%2$s pabeigti)"
"Notiek %1$s instalēšana"
"%1$s logrīki"
+ "Logrīku saraksts"
+ "Logrīku saraksts aizvērts"
"Pievienot sākuma ekrānam"
"Pārvietot vienumu šeit"
"Vienums pievienots sākuma ekrānam"
@@ -114,9 +126,6 @@
"Izveidot mapi ar: %1$s"
"Mape izveidota"
"Pārvietot uz sākuma ekrānu"
- "Pārvietot ekrānu pa kreisi"
- "Pārvietot ekrānu pa labi"
- "Ekrāns pārvietots"
"Mainīt lielumu"
"Palielināt platumu"
"Palielināt augstumu"
@@ -124,8 +133,16 @@
"Samazināt augstumu"
"Logrīka lielums mainīts — platums: %1$s, augstums: %2$s."
"Saīsnes"
- "%1$d saīsnes lietotnei %2$s"
- "%1$d saīsnes un %2$d paziņojumi lietotnei %3$s"
+ "Saīsnes un paziņojumi"
"Nerādīt"
"Paziņojums netiek rādīts"
+ "Personīgās lietotnes"
+ "Darba lietotnes"
+ "Darba profils"
+ "Meklējiet darba lietotnes šeit"
+ "Katrai darba lietotnei ir emblēma, un jūsu organizācija aizsargā šīs lietotnes. Lai varētu ērtāk piekļūt lietotnēm, pārvietojiet tās uz sākuma ekrānu."
+ "Pārvalda jūsu organizācija"
+ "Paziņojumi un lietotnes ir izslēgtas"
+ "Aizvērt"
+ "Aizvērta"
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
new file mode 100644
index 0000000000..54d9c8054a
--- /dev/null
+++ b/res/values-mk-rMK/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Стартер3"
+
+ "Работа"
+ "Апликацијата не е инсталирана."
+ "Апликацијата не е достапна"
+ "Преземената апликација е оневозможена во безбеден режим"
+ "Додатоците се оневозможени во безбеден режим"
+ "Кратенката не е достапна"
+ "Почетен екран"
+ "Приспособени дејства"
+ "Допри и задржи за да се избере виџетот."
+ "Допрете двапати и задржете за да изберете додаток или да користите приспособени дејства."
+ "%1$d × %2$d"
+ "%1$d широк на %2$d висок"
+ "Допрете и задржете за рачно поставување"
+ "Додај автоматски"
+ "Пребарувајте апликации"
+ "Се вчитуваат апликации…"
+ "Не се најдени апликации што одговараат на „%1$s“"
+ "Пребарај други апликации"
+ "Известувања"
+ "Допрете двапати и задржете за избор на кратенка."
+ "Допрете двапати и задржете за избор на кратенка или користете приспособени дејства."
+ "Нема повеќе простор на овој екран на почетната страница."
+ "Нема повеќе простор на лентата „Омилени“"
+ "Список со апликации"
+ "Список со лични апликации"
+ "Список со апликации за работа"
+ "Почетна страница"
+ "Отстрани"
+ "Деинсталирај"
+ "Инф. за апликација"
+ "Инсталирај"
+ "инсталирај кратенки"
+ "Овозможува апликацијата да додава кратенки без интервенција на корисникот."
+ "чита поставки и кратенки на почетна страница"
+ "Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."
+ "пишува поставки и кратенки на почетна страница"
+ "Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."
+ "%1$s нема дозвола за телефонски повици"
+ "Проблем при вчитувањето на виџетот"
+ "Поставување"
+ "Ова е системска апликација и не може да се деинсталира."
+ "Неименувана папка"
+ "%1$s е оневозможена"
+
+ - %1$s има %2$d известување
+ - %1$s има %2$d известувања
+
+ "Страница %1$d од %2$d"
+ "Екран на почетна страница %1$d од %2$d"
+ "Нова страница на почетен екран"
+ "Отворена е папка, %1$d на %2$d"
+ "Допрете за да ја затворите папката"
+ "Допрете за да го зачувате преименувањето"
+ "Папката е затворена"
+ "Папката е преименувана во %1$s"
+ "Папка: %1$s"
+ "Виџети"
+ "Тапети"
+ "Поставки за Home"
+ "Оневозможено од администраторот"
+ "Дозволете ротација на Почетниот екран"
+ "Кога телефонот се ротира"
+ "Точки за известување"
+ "Вклучено"
+ "Исклучено"
+ "Потребен е пристап до известувањата"
+ "За да се прикажуваат „Точки за известување“, вклучете ги известувањата за апликацијата %1$s"
+ "Промени ги поставките"
+ "Прикажи точки за известување"
+ "Додај икона на почетниот екран"
+ "За нови апликации"
+ "Променете ја формата на иконата"
+ "на „Почетен екран“"
+ "Користи ја стандардната поставка на системот"
+ "Квадрат"
+ "Заоблен квадрат"
+ "Круг"
+ "Солза"
+ "Се применуваат промените на формата на иконата"
+ "Непознато"
+ "Отстрани"
+ "Барај"
+ "Апликацијата не е инсталирана"
+ "Апликацијата за оваа икона не е инсталирана. Може да ја отстраните или да се обидете да ја најдете апликацијата и да ја инсталирате рачно."
+ "Се презема %1$s, %2$s завршено"
+ "%1$s чека да се инсталира"
+ "Виџети за %1$s"
+ "Додај на Почетен екран"
+ "Премести ја ставката овде"
+ "Ставката е додадена на почетниот екран"
+ "Ставката е отстранета"
+ "Премести ја ставката"
+ "Премести во ред %1$s колона %2$s"
+ "Премести на место %1$s"
+ "Премести на место %1$s во омилени"
+ "Ставката е преместена"
+ "Додај во папката: %1$s"
+ "Додај во папка со %1$s"
+ "Ставката е додадена во папката"
+ "Создај папка со: %1$s"
+ "Папката е создадена"
+ "Премести на Почетен екран"
+ "Промени големина"
+ "Зголеми ширина"
+ "Зголеми висина"
+ "Намали ширина"
+ "Намали висина"
+ "Големината на виџетот е променета на ширина %1$s висина %2$s"
+ "Кратенки"
+ "%1$d кратенки за %2$s"
+ "%1$d кратенки и %2$d известувања за %3$s"
+ "Отфрли"
+ "Известувањето е отфрлено"
+ "Лично"
+ "За работа"
+ "Работен профил"
+ "Најдете апликации за работа тука"
+ "Секоја апликација за работа има значка, а организацијата се грижи за нејзината безбедност. За полесен пристап, преместете ги апликациите на почетниот екран."
+ "Управувано од вашата организација"
+ "Известувањата и апликациите се исклучени"
+ "Затвори"
+ "Затворено"
+
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 7d95a23a6c..e5dd02776b 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -40,13 +40,18 @@
"Не се најдени апликации што одговараат на „%1$s“"
"Пребарај други апликации"
"Известувања"
+ "Допрете двапати и задржете за избор на кратенка."
+ "Допрете двапати и задржете за избор на кратенка или користете приспособени дејства."
"Нема повеќе простор на овој екран на почетната страница."
"Нема повеќе простор на лентата „Омилени“"
"Список со апликации"
+ "Список со лични апликации"
+ "Список со апликации за работа"
"Почетна страница"
"Отстрани"
"Деинсталирај"
"Инф. за апликација"
+ "Инсталирај"
"инсталирај кратенки"
"Овозможува апликацијата да додава кратенки без интервенција на корисникот."
"чита поставки и кратенки на почетна страница"
@@ -59,6 +64,10 @@
"Ова е системска апликација и не може да се деинсталира."
"Неименувана папка"
"%1$s е оневозможена"
+
+ - %1$s има %2$d известување
+ - %1$s има %2$d известувања
+
"Страница %1$d од %2$d"
"Екран на почетна страница %1$d од %2$d"
"Нова страница на почетен екран"
@@ -68,23 +77,23 @@
"Папката е затворена"
"Папката е преименувана во %1$s"
"Папка: %1$s"
- "Додатоци"
- "Позадини"
+ "Виџети"
+ "Тапети"
"Поставки за Home"
"Оневозможено од администраторот"
- "Краток преглед"
"Дозволете ротација на Почетниот екран"
"Кога телефонот се ротира"
- "Тековната поставка на Екранот не дозволува ротација"
"Точки за известување"
"Вклучено"
"Исклучено"
"Потребен е пристап до известувањата"
"За да се прикажуваат „Точки за известување“, вклучете ги известувањата за апликацијата %1$s"
"Промени ги поставките"
- "Додајте икона на почетниот екран"
+ "Прикажи точки за известување"
+ "Додај икона на почетниот екран"
"За нови апликации"
"Променете ја формата на иконата"
+ "на „Почетен екран“"
"Користи ја стандардната поставка на системот"
"Квадрат"
"Заоблен квадрат"
@@ -99,6 +108,8 @@
"Се презема %1$s, %2$s завршено"
"%1$s чека да се инсталира"
"Виџети за %1$s"
+ "Список со виџети"
+ "Списокот со виџети е затворен"
"Додај на Почетен екран"
"Премести ја ставката овде"
"Ставката е додадена на почетниот екран"
@@ -114,9 +125,6 @@
"Создај папка со: %1$s"
"Папката е создадена"
"Премести на Почетен екран"
- "Движи го екранот налево"
- "Движи го екранот надесно"
- "Екранот е преместен"
"Промени големина"
"Зголеми ширина"
"Зголеми висина"
@@ -124,8 +132,16 @@
"Намали висина"
"Големината на виџетот е променета на ширина %1$s висина %2$s"
"Кратенки"
- "%1$d кратенки за %2$s"
- "%1$d кратенки и %2$d известувања за %3$s"
+ "Кратенки и известувања"
"Отфрли"
"Известувањето е отфрлено"
+ "Лично"
+ "За работа"
+ "Работен профил"
+ "Најдете апликации за работа тука"
+ "Секоја апликација за работа има значка, а организацијата се грижи за нејзината безбедност. За полесен пристап, преместете ги апликациите на почетниот екран."
+ "Управувано од вашата организација"
+ "Известувањата и апликациите се исклучени"
+ "Затвори"
+ "Затворено"
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
new file mode 100644
index 0000000000..a0609333c9
--- /dev/null
+++ b/res/values-ml-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "ലോഞ്ചർ3"
+
+ "ഔദ്യോഗികം"
+ "അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല."
+ "അപ്ലിക്കേഷൻ ലഭ്യമല്ല"
+ "ഡൗൺലോഡുചെയ്ത അപ്ലിക്കേഷൻ സുരക്ഷാ മോഡിൽ പ്രവർത്തനരഹിതമാക്കി"
+ "സുരക്ഷിത മോഡിൽ വിജറ്റുകൾ പ്രവർത്തനരഹിതമാക്കി"
+ "കുറുക്കുവഴി ലഭ്യമല്ല"
+ "ഹോം സ്ക്രീൻ"
+ "ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ"
+ "ഒരു വിജറ്റ് ചേർക്കുന്നതിന് അത് സ്പർശിച്ച് പിടിക്കുക."
+ "വിജറ്റ് തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."
+ "%1$d × %2$d"
+ "%1$d വീതിയും %2$d ഉയരവും"
+ "സ്വമേധയാ സ്ഥാപിക്കുന്നതിന് സ്പർശിച്ചുപിടിക്കുക"
+ "സ്വയമേവ ചേർക്കുക"
+ "ആപ്പുകൾ തിരയുക"
+ "ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."
+ "\"%1$s\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"
+ "കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"
+ "അറിയിപ്പുകൾ"
+ "തിരഞ്ഞെടുക്കുന്നതിന് കുറുക്കുവഴി സ്പർശിച്ച് പിടിക്കുക."
+ "കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ 2 തവണ ടാപ്പ് ചെയ്ത് പിടിക്കുക."
+ "ഈ ഹോം സ്ക്രീനിൽ ഒഴിവൊന്നുമില്ല."
+ "പ്രിയപ്പെട്ടവയുടെ ട്രേയിൽ ഒഴിവൊന്നുമില്ല"
+ "അപ്ലിക്കേഷനുകളുടെ ലിസ്റ്റ്"
+ "വ്യക്തിഗത ആപ്പുകളുടെ ലിസ്റ്റ്"
+ "ഔദ്യോഗിക ആപ്പുകളുടെ ലിസ്റ്റ്"
+ "ഹോം"
+ "നീക്കംചെയ്യുക"
+ "അൺഇൻസ്റ്റാളുചെയ്യുക"
+ "ആപ്പ് വിവരം"
+ "ഇൻസ്റ്റാൾ ചെയ്യുക"
+ "കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"
+ "ഉപയോക്തൃ ഇടപെടൽ ഇല്ലാതെ കുറുക്കുവഴികൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."
+ "ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യുക"
+ "ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."
+ "ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റൈറ്റുചെയ്യുക"
+ "ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."
+ "ഫോൺ കോൾ ചെയ്യാൻ %1$s എന്നതിനെ അനുവദിച്ചിട്ടില്ല"
+ "വിജറ്റ് ലോഡുചെയ്യുന്നതിൽ പ്രശ്നമുണ്ട്"
+ "സജ്ജീകരിക്കുക"
+ "ഇതൊരു സിസ്റ്റം അപ്ലിക്കേഷനായതിനാൽ അൺഇൻസ്റ്റാളുചെയ്യാനാവില്ല."
+ "പേരുനൽകാത്ത ഫോൾഡർ"
+ "%1$s പ്രവർത്തനരഹിതമാക്കി"
+
+ - %1$s-ന്, %2$d അറിയിപ്പുകൾ ഉണ്ട്
+ - %1$s-ന്, %2$d അറിയിപ്പ് ഉണ്ട്
+
+ "പേജ് %1$d / %2$d"
+ "ഹോം സ്ക്രീൻ %1$d / %2$d"
+ "പുതിയ ഹോം സ്ക്രീൻ പേജ്"
+ "ഫോൾഡർ തുറന്നു, %1$d / %2$d"
+ "ഫോൾഡർ അടയ്ക്കുന്നതിന് ടാപ്പുചെയ്യുക"
+ "പേരുമാറ്റം സംരക്ഷിക്കുന്നതിന് ടാപ്പുചെയ്യുക"
+ "ഫോൾഡർ അടച്ചു"
+ "ഫോൾഡറിന്റെ പേര് %1$s എന്നായി മാറ്റി"
+ "ഫോൾഡർ: %1$s"
+ "വിജറ്റുകൾ"
+ "വാൾപേപ്പർ"
+ "ഹോം ക്രമീകരണം"
+ "അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"
+ "ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"
+ "ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"
+ "അറിയിപ്പ് ഡോട്ടുകൾ"
+ "ഓൺ"
+ "ഓഫ്"
+ "അറിയിപ്പിനായുള്ള ആക്സസ് ആവശ്യമാണ്"
+ "അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുന്നതിന്, %1$s എന്നയാളിനായുള്ള ആപ്പ് അറിയിപ്പുകൾ ഓണാക്കുക"
+ "ക്രമീകരണം മാറ്റുക"
+ "അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുക"
+ "ഹോം സ്ക്രീനിലേക്ക് ഐക്കൺ ചേർക്കുക"
+ "പുതിയ ആപ്പുകൾക്ക്"
+ "ഐക്കണിന്റെ ആകാരം മാറ്റുക"
+ "ഹോം സ്ക്രീനിൽ"
+ "സിസ്റ്റം ഡിഫോൾട്ട് ഉപയോഗിക്കുക"
+ "ചതുരം"
+ "ചതുരവൃത്തം"
+ "വൃത്തം"
+ "കണ്ണുനീര് തുള്ളി"
+ "ഐക്കൺ ആകാര മാറ്റങ്ങൾ പ്രയോഗിക്കുന്നു"
+ "അജ്ഞാതം"
+ "നീക്കംചെയ്യുക"
+ "തിരയുക"
+ "ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല"
+ "ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വമേധയാ ഇൻസ്റ്റാളുചെയ്യുക."
+ "%1$s ഡൗൺലോഡ് ചെയ്യുന്നു, %2$s പൂർത്തിയായി"
+ "ഇൻസ്റ്റാൾ ചെയ്യാൻ %1$s കാക്കുന്നു"
+ "%1$s വിജറ്റുകൾ"
+ "ഹോം സ്ക്രീനിൽ ചേർക്കുക"
+ "ഇനം ഇവിടേക്ക് നീക്കുക"
+ "ഹോം സ്ക്രീനിൽ ഇനം ചേർത്തു"
+ "ഇനം നീക്കംചെയ്തു"
+ "ഇനം നീക്കുക"
+ "വരി %1$s നിര %2$s-ലേക്ക് നീക്കുക"
+ "%1$s-ലേക്ക് നീക്കുക"
+ "ഇഷ്ടമുള്ള %1$s സ്ഥാനത്തേക്ക് നീക്കുക"
+ "ഇനം നീക്കി"
+ "ഫോൾഡറിൽ ചേർക്കുക: %1$s"
+ "%1$s ഉള്ള ഫോൾഡറിൽ ചേർക്കുക"
+ "ഫോൾഡറിൽ ഇനം ചേർത്തു"
+ "ഇതുപയോഗിച്ച് ഫോൾഡർ സൃഷ്ടിക്കുക: %1$s"
+ "ഫോൾഡർ സൃഷ്ടിച്ചു"
+ "ഹോം സ്ക്രീനിലേക്ക് നീക്കുക"
+ "വലുപ്പംമാറ്റുക"
+ "വീതി കൂട്ടുക"
+ "ഉയരം കൂട്ടുക"
+ "വീതി കുറയ്ക്കുക"
+ "ഉയരം കുറയ്ക്കുക"
+ "വീതി %1$s ഉയരം %2$s-ലേക്ക് വിഡ്ജെറ്റിന്റെ വലുപ്പം മാറ്റി"
+ "കുറുക്കുവഴികൾ"
+ "%2$s ആപ്പിനുള്ള %1$d കുറുക്കുവഴികൾ"
+ "%3$s ആപ്പിനായുള്ള %1$d കുറുക്കുവഴികളും %2$d അറിയിപ്പുകളും"
+ "നിരസിക്കുക"
+ "അറിയിപ്പ് നിരസിച്ചു"
+ "വ്യക്തിപരം"
+ "ജോലി"
+ "ഔദ്യോഗിക പ്രൊഫൈൽ"
+ "ഔദ്യോഗിക ആപ്പുകൾ ഇവിടെ കണ്ടെത്തുക"
+ "എല്ലാ ഔദ്യോഗിക ആപ്പിനും ഒരു ബാഡ്ജ് ഉണ്ട്, നിങ്ങളുടെ സ്ഥാപനം അത് സുരക്ഷിതമായി സൂക്ഷിക്കുന്നു. എളുപ്പത്തിൽ ആക്സസ് ചെയ്യാൻ ആപ്പുകളെ ഹോം സ്ക്രീനിലേക്ക് നീക്കുക."
+ "നിങ്ങളുടെ സ്ഥാപനം നിയന്ത്രിക്കുന്നത്"
+ "അറിയിപ്പുകളും ആപ്പുകളും ഓഫാണ്"
+ "അടയ്ക്കുക"
+ "അടച്ചു"
+
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 0cc7aa023c..d6a2fd1a92 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"
"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"
"അറിയിപ്പുകൾ"
+ "തിരഞ്ഞെടുക്കുന്നതിന് കുറുക്കുവഴി സ്പർശിച്ച് പിടിക്കുക."
+ "കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ 2 തവണ ടാപ്പ് ചെയ്ത് പിടിക്കുക."
"ഈ ഹോം സ്ക്രീനിൽ ഒഴിവൊന്നുമില്ല."
"പ്രിയപ്പെട്ടവയുടെ ട്രേയിൽ ഒഴിവൊന്നുമില്ല"
"അപ്ലിക്കേഷനുകളുടെ ലിസ്റ്റ്"
+ "വ്യക്തിഗത ആപ്പുകളുടെ ലിസ്റ്റ്"
+ "ഔദ്യോഗിക ആപ്പുകളുടെ ലിസ്റ്റ്"
"ഹോം"
"നീക്കംചെയ്യുക"
"അൺഇൻസ്റ്റാളുചെയ്യുക"
"ആപ്പ് വിവരം"
+ "ഇൻസ്റ്റാൾ ചെയ്യുക"
"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"
"ഉപയോക്തൃ ഇടപെടൽ ഇല്ലാതെ കുറുക്കുവഴികൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."
"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യുക"
@@ -59,6 +64,10 @@
"ഇതൊരു സിസ്റ്റം അപ്ലിക്കേഷനായതിനാൽ അൺഇൻസ്റ്റാളുചെയ്യാനാവില്ല."
"പേരുനൽകാത്ത ഫോൾഡർ"
"%1$s പ്രവർത്തനരഹിതമാക്കി"
+
+ - %1$s-ന്, %2$d അറിയിപ്പുകൾ ഉണ്ട്
+ - %1$s-ന്, %2$d അറിയിപ്പ് ഉണ്ട്
+
"പേജ് %1$d / %2$d"
"ഹോം സ്ക്രീൻ %1$d / %2$d"
"പുതിയ ഹോം സ്ക്രീൻ പേജ്"
@@ -72,19 +81,19 @@
"വാൾപേപ്പർ"
"ഹോം ക്രമീകരണം"
"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"
- "അവലോകനം"
"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"
"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"
- "നിലവിലെ ഡിസ്പ്ലേ ക്രമീകരണം തിരിക്കൽ അനുവദിക്കുന്നില്ല"
"അറിയിപ്പ് ഡോട്ടുകൾ"
"ഓൺ"
"ഓഫ്"
"അറിയിപ്പിനായുള്ള ആക്സസ് ആവശ്യമാണ്"
"അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുന്നതിന്, %1$s എന്നയാളിനായുള്ള ആപ്പ് അറിയിപ്പുകൾ ഓണാക്കുക"
"ക്രമീകരണം മാറ്റുക"
+ "അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുക"
"ഹോം സ്ക്രീനിലേക്ക് ഐക്കൺ ചേർക്കുക"
"പുതിയ ആപ്പുകൾക്ക്"
"ഐക്കണിന്റെ ആകാരം മാറ്റുക"
+ "ഹോം സ്ക്രീനിൽ"
"സിസ്റ്റം ഡിഫോൾട്ട് ഉപയോഗിക്കുക"
"ചതുരം"
"ചതുരവൃത്തം"
@@ -99,6 +108,10 @@
"%1$s ഡൗൺലോഡ് ചെയ്യുന്നു, %2$s പൂർത്തിയായി"
"ഇൻസ്റ്റാൾ ചെയ്യാൻ %1$s കാക്കുന്നു"
"%1$s വിജറ്റുകൾ"
+
+
+
+
"ഹോം സ്ക്രീനിൽ ചേർക്കുക"
"ഇനം ഇവിടേക്ക് നീക്കുക"
"ഹോം സ്ക്രീനിൽ ഇനം ചേർത്തു"
@@ -114,9 +127,6 @@
"ഇതുപയോഗിച്ച് ഫോൾഡർ സൃഷ്ടിക്കുക: %1$s"
"ഫോൾഡർ സൃഷ്ടിച്ചു"
"ഹോം സ്ക്രീനിലേക്ക് നീക്കുക"
- "സ്ക്രീൻ ഇടത്തേക്ക് നീക്കുക"
- "സ്ക്രീൻ വലത്തേക്ക് നീക്കുക"
- "സ്ക്രീൻ നീക്കി"
"വലുപ്പംമാറ്റുക"
"വീതി കൂട്ടുക"
"ഉയരം കൂട്ടുക"
@@ -124,8 +134,16 @@
"ഉയരം കുറയ്ക്കുക"
"വീതി %1$s ഉയരം %2$s-ലേക്ക് വിഡ്ജെറ്റിന്റെ വലുപ്പം മാറ്റി"
"കുറുക്കുവഴികൾ"
- "%2$s ആപ്പിനുള്ള %1$d കുറുക്കുവഴികൾ"
- "%3$s ആപ്പിനായുള്ള %1$d കുറുക്കുവഴികളും %2$d അറിയിപ്പുകളും"
+ "കുറുക്കുവഴികളും അറിയിപ്പുകളും"
"നിരസിക്കുക"
"അറിയിപ്പ് നിരസിച്ചു"
+ "വ്യക്തിപരം"
+ "ജോലി"
+ "ഔദ്യോഗിക പ്രൊഫൈൽ"
+ "ഔദ്യോഗിക ആപ്പുകൾ ഇവിടെ കണ്ടെത്തുക"
+ "എല്ലാ ഔദ്യോഗിക ആപ്പിനും ഒരു ബാഡ്ജ് ഉണ്ട്, നിങ്ങളുടെ സ്ഥാപനം അത് സുരക്ഷിതമായി സൂക്ഷിക്കുന്നു. എളുപ്പത്തിൽ ആക്സസ് ചെയ്യാൻ ആപ്പുകളെ ഹോം സ്ക്രീനിലേക്ക് നീക്കുക."
+ "നിങ്ങളുടെ സ്ഥാപനം നിയന്ത്രിക്കുന്നത്"
+ "അറിയിപ്പുകളും ആപ്പുകളും ഓഫാണ്"
+ "അടയ്ക്കുക"
+ "അടച്ചു"
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000000..a3507c5bb8
--- /dev/null
+++ b/res/values-mn-rMN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Ажил"
+ "Апп суугаагүй байна."
+ "Апп-г ашиглах боломжгүй"
+ "Татаж авсан апп-г Аюулгүй горим дотроос идэвхгүйжүүлсэн"
+ "Safe горимд виджетүүдийг идэвхгүйжүүлсэн"
+ "Товчлол алга"
+ "Үндсэн нүүр"
+ "Захиалгат үйлдэл"
+ "Виджетийг авах бол хүрээд барина уу."
+ "Жижиг хэрэгсэл авах болон тохируулсан үйлдлийг ашиглахын тулд 2 удаа товшоод барина уу."
+ "%1$d × %2$d"
+ "%1$d өргөн %2$d өндөр"
+ "Гараар байршуулахын тулд дараад хүлээнэ үү"
+ "Автоматаар нэмэх"
+ "Апп хайх"
+ "Аппыг ачааллаж байна..."
+ "\"%1$s\"-д тохирох апп олдсонгүй"
+ "Бусад апп-г хайх"
+ "Мэдэгдэл"
+ "Товчлол авах бол удаан дарна уу."
+ "Товчлол авах эсвэл тохируулсан үйлдлийг ашиглахын тулд давхар товшоод хүлээнэ үү."
+ "Энэ Нүүр дэлгэц зайгүй."
+ "\"Дуртай\" трей дээр өөр зай байхгүй байна"
+ "Апп-н жагсаалт"
+ "Хувийн аппын жагсаалт"
+ "Ажлын аппын жагсаалт"
+ "Нүүр"
+ "Арилгах"
+ "Устгах"
+ "Апп-н мэдээлэл"
+ "Суулгах"
+ "товчлол суулгах"
+ "Апп нь хэрэглэгчийн оролцоогүйгээр товчлолыг нэмэж чадна"
+ "Нүүрний тохиргоо болон товчлолыг унших"
+ "Апп нь Нүүрэндэх товчлол болон тохиргоог уншиж чадна."
+ "Нүүрний тохиргоо болон товчлолыг бичих"
+ "Апп нь Нүүрэндэх товчлол болон тохиргоог өөрчилж чадна."
+ "%1$s утасны дуудлага хийх боломжгүй"
+ "Виджет ачаалахад асуудал гарав"
+ "Тохируулга"
+ "Энэ апп нь системийн апп ба устгах боломжгүй."
+ "Нэргүй фолдер"
+ "%1$s-г идэвхгүй болгосон"
+
+ - %1$s, %2$d мэдэгдэл байна
+ - %1$s, %2$d мэдэгдэл байна
+
+ "%2$d-н %1$d хуудас"
+ "%2$d-н Нүүр дэлгэц %1$d"
+ "Шинэ үндсэн нүүр хуудас"
+ "%1$d %2$d фолдер нээгдэв"
+ "Фолдерийг хаахын тулд дарна уу"
+ "Шинэ нэрийг хадгалахын тулд дарна уу."
+ "Фолдер хаагдав"
+ "Фолдерын нэр %1$s болов"
+ "Фолдер: %1$s"
+ "Виджет"
+ "Ханын зураг"
+ "Нүүр хуудасны тохиргоо"
+ "Таны админ идэвхгүй болгосон"
+ "Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"
+ "Утсыг эргүүлсэн үед"
+ "Мэдэгдлийн цэг"
+ "Асаалттай"
+ "Унтраалттай"
+ "Мэдэгдлийн хандалт шаардлагатай"
+ "Мэдэгдлийн цэгийг харуулахын тулд %1$s-д аппын мэдэгдлийг асаана уу"
+ "Тохиргоог өөрчлөх"
+ "Мэдэгдлийн цэгийг харуулах"
+ "Нүүр хуудаст дүрс тэмдэг нэмэх"
+ "Шинэ аппад зориулсан"
+ "Дүрс тэмдгийн хэлбэрийг өөрчлөх"
+ "Үндсэн нүүр хэсэгт"
+ "Системийн өгөгдмөл тохиргоог ашиглах"
+ "Дөрвөлжин"
+ "Мохоо өнцөгтэй дөрвөлжин"
+ "Дугуй"
+ "Дусал"
+ "Дүрс тэмдгийн хэлбэрийг өөрчилж байна"
+ "Тодорхойгүй"
+ "Устгах"
+ "Хайх"
+ "Энэ апп-г суулгаагүй байна"
+ "Энэ дүрсний апп-г суулгаагүй байна. Та үүнийг устгах буюу апп-г хайж суулгах боломжтой."
+ "%1$s-г татаж байна, %2$s татсан"
+ "%1$s нь суулгахыг хүлээж байна"
+ "%1$s жижиг хэрэгсэл"
+ "Нүүр дэлгэц нэмэх"
+ "Энд байршуулах"
+ "Нүүр дэлгэцэнд нэмсэн зүйл"
+ "Арилгасан зүйл"
+ "Зөөх"
+ "%1$s мөр %2$s баганад зөөх"
+ "Байршил %1$s-д зөөх"
+ "Дуртай байршил болох %1$s-д зөөх"
+ "Зөөвөрлөсөн зүйл"
+ "Хавтас: %1$s руу нэм"
+ "%1$s-тай хавтас нэмэх"
+ "Хавтсанд нэмэгдсэн зүйл"
+ "Хавтсыг: %1$s нэрээр үүсгэ"
+ "Үүсгэсэн хавтас"
+ "Нүүр дэлгэц рүү зөөх"
+ "Хэмжээг өөрчлөх"
+ "Өргөсгөх"
+ "Өндөрсгөх"
+ "Нарийсгах"
+ "Намсгах"
+ "Виджэтийн өргөн %1$s, өндөр %2$s болсон"
+ "Товчлол"
+ "%2$s-н %1$d товчлол"
+ "%1$d товчлол болон %3$s-н %2$d мэдэгдэл"
+ "Хаах"
+ "Мэдэгдлийг хаасан"
+ "Хувийн"
+ "Ажил"
+ "Ажлын профайл"
+ "Ажлын аппыг эндээс олно уу"
+ "Ажлын апп тус бүр тэмдэгтэй ба эдгээрийг танай байгууллагаас аюулгүй байлгадаг. Аппуудад хялбар хандахын тулд тэдгээрийг Үндсэн нүүр хэсэгт зөөнө үү."
+ "Танай байгууллагаас удирддаг"
+ "Мэдэгдэл, апп унтраалттай байна"
+ "Хаах"
+ "Хаасан"
+
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 22479cc3e4..9fbb1e51e4 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\"-д тохирох апп олдсонгүй"
"Бусад апп-г хайх"
"Мэдэгдэл"
+ "Товчлол авах бол удаан дарна уу."
+ "Товчлол авах эсвэл тохируулсан үйлдлийг ашиглахын тулд давхар товшоод хүлээнэ үү."
"Энэ Нүүр дэлгэц зайгүй."
"\"Дуртай\" трей дээр өөр зай байхгүй байна"
"Апп-н жагсаалт"
+ "Хувийн аппын жагсаалт"
+ "Ажлын аппын жагсаалт"
"Нүүр"
"Арилгах"
"Устгах"
"Апп-н мэдээлэл"
+ "Суулгах"
"товчлол суулгах"
"Апп нь хэрэглэгчийн оролцоогүйгээр товчлолыг нэмэж чадна"
"Нүүрний тохиргоо болон товчлолыг унших"
@@ -59,6 +64,10 @@
"Энэ апп нь системийн апп ба устгах боломжгүй."
"Нэргүй фолдер"
"%1$s-г идэвхгүй болгосон"
+
+ - %1$s, %2$d мэдэгдэл байна
+ - %1$s, %2$d мэдэгдэл байна
+
"%2$d-н %1$d хуудас"
"%2$d-н Нүүр дэлгэц %1$d"
"Шинэ үндсэн нүүр хуудас"
@@ -72,19 +81,19 @@
"Ханын зураг"
"Нүүр хуудасны тохиргоо"
"Таны админ идэвхгүй болгосон"
- "Тойм"
"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"
"Утсыг эргүүлсэн үед"
- "Дэлгэцийн одоогийн тохиргоогоор эргүүлэх боломжгүй"
"Мэдэгдлийн цэг"
"Асаалттай"
"Унтраалттай"
"Мэдэгдлийн хандалт шаардлагатай"
"Мэдэгдлийн цэгийг харуулахын тулд %1$s-д аппын мэдэгдлийг асаана уу"
"Тохиргоог өөрчлөх"
+ "Мэдэгдлийн цэгийг харуулах"
"Нүүр хуудаст дүрс тэмдэг нэмэх"
"Шинэ аппад зориулсан"
"Дүрс тэмдгийн хэлбэрийг өөрчлөх"
+ "Үндсэн нүүр хэсэгт"
"Системийн өгөгдмөл тохиргоог ашиглах"
"Дөрвөлжин"
"Мохоо өнцөгтэй дөрвөлжин"
@@ -99,6 +108,8 @@
"%1$s-г татаж байна, %2$s татсан"
"%1$s нь суулгахыг хүлээж байна"
"%1$s жижиг хэрэгсэл"
+ "Жижиг хэрэгслийн жагсаалт"
+ "Жижиг хэрэгслийн жагсаалтыг хаасан"
"Нүүр дэлгэц нэмэх"
"Энд байршуулах"
"Нүүр дэлгэцэнд нэмсэн зүйл"
@@ -114,9 +125,6 @@
"Хавтсыг: %1$s нэрээр үүсгэ"
"Үүсгэсэн хавтас"
"Нүүр дэлгэц рүү зөөх"
- "Дэлгэцийг зүүн тийш зөөх"
- "Дэлгэцийг баруун тийш зөөх"
- "Дэлгэцийг зөөсөн"
"Хэмжээг өөрчлөх"
"Өргөсгөх"
"Өндөрсгөх"
@@ -124,8 +132,16 @@
"Намсгах"
"Виджэтийн өргөн %1$s, өндөр %2$s болсон"
"Товчлол"
- "%2$s-н %1$d товчлол"
- "%1$d товчлол болон %3$s-н %2$d мэдэгдэл"
+ "Товчлол болон мэдэгдэл"
"Хаах"
"Мэдэгдлийг хаасан"
+ "Хувийн"
+ "Ажил"
+ "Ажлын профайл"
+ "Ажлын аппыг эндээс олно уу"
+ "Ажлын апп тус бүр тэмдэгтэй ба эдгээрийг танай байгууллагаас аюулгүй байлгадаг. Аппуудад хялбар хандахын тулд тэдгээрийг Үндсэн нүүр хэсэгт зөөнө үү."
+ "Танай байгууллагаас удирддаг"
+ "Мэдэгдэл, апп унтраалттай байна"
+ "Хаах"
+ "Хаасан"
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
new file mode 100644
index 0000000000..bf1e188058
--- /dev/null
+++ b/res/values-mr-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "कार्य"
+ "अॅप इंस्टॉल केलेला नाही."
+ "अॅप उपलब्ध नाही"
+ "डाउनलोड केलेला अॅप सुरक्षित मोड मध्ये अक्षम केला"
+ "विजेट सुरक्षित मोडमध्ये अक्षम झाले"
+ "शॉर्टकट उपलब्ध नाही"
+ "होम स्क्रीन"
+ "कस्टम क्रिया"
+ "विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."
+ "एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा कस्टम क्रिया वापरा."
+ "%1$d × %2$d"
+ "%1$d रूंद बाय %2$d उंच"
+ "स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"
+ "अापोआप जोडा"
+ "अॅप्स शोधा"
+ "अॅप्स लोड करत आहे…"
+ "\"%1$s\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"
+ "अधिक अॅप्स शोधा"
+ "सूचना"
+ "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."
+ "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."
+ "या मुख्य स्क्रीनवर आणखी जागा नाही."
+ "आवडीच्या ट्रे मध्ये आणखी जागा नाही"
+ "अॅप्स सूची"
+ "वैयक्तिक अॅप्स सूची"
+ "कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची"
+ "होम"
+ "काढा"
+ "अनइंस्टॉल करा"
+ "अॅप माहिती"
+ "इंस्टॉल करा"
+ "शॉर्टकट स्थापित करा"
+ "वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अॅप ला अनुमती देते."
+ "होम सेटिंग्ज आणि शॉर्टकट वाचा"
+ "मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."
+ "होम सेटिंग्ज आणि शॉर्टकट लिहा"
+ "मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."
+ "%1$s ला फोन कॉल करण्याची अनुमती नाही"
+ "विजेट लोड करण्यात समस्या"
+ "सेटअप"
+ "हा सिस्टम अॅप आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."
+ "अनामित फोल्डर"
+ "%1$s अक्षम केला आहे"
+
+ - %1$s, कडे %2$d सूचना आहे
+ - %1$s, कडे %2$d सूचना आहेत
+
+ "%2$d पैकी %1$d पृष्ठ"
+ "%2$d पैकी %1$d मुख्य स्क्रीन"
+ "नवीन मुख्य स्क्रीन पृष्ठ"
+ "फोल्डर उघडले, %1$d बाय %2$d"
+ "फोल्डर बंद करण्यासाठी टॅप करा"
+ "पुनर्नामित करणे सेव्ह करण्यासाठी टॅप करा"
+ "फोल्डर बंद"
+ "फोल्डरचे नाव बदलून %1$s असे ठेवले"
+ "फोल्डर: %1$s"
+ "विजेट"
+ "वॉलपेपर"
+ "होम सेटिंग्ज"
+ "आपल्या प्रशासकाने अक्षम केले"
+ "मुख्यस्क्रीन फिरविण्यास अनुमती द्या"
+ "फोन फिरविला जातो तेव्हा"
+ "सूचना बिंदू"
+ "चालू"
+ "बंद"
+ "सूचनांच्या अॅक्सेसची आवश्यकता आहे"
+ "सूचना बिंदू दाखवण्यासाठी, %1$s साठी अॅप सूचना चालू करा"
+ "सेटिंग्ज बदला"
+ "सूचना बिंदू दाखवा"
+ "होम स्क्रीनवर आयकन जोडा"
+ "नवीन अॅप्ससाठी"
+ "चिन्हाचा आकार बदला"
+ "होम स्क्रीनवर"
+ "सिस्टमचे डीफॉल्ट वापरा"
+ "चौरस"
+ "गोलाकार चौरस"
+ "वर्तुळ"
+ "अश्रू"
+ "चिन्हाचा आकार बदल लागू करत आहे"
+ "अज्ञात"
+ "काढा"
+ "शोधा"
+ "हा अॅप इंस्टॉल केलेला नाही"
+ "या चिन्हासाठी अॅप इंस्टॉल केलेला नाही. तुम्ही ते काढू शकता किंवा अॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे इंस्टॉल करू शकता."
+ "%1$s डाउनलोड होत आहे , %2$s पूर्ण झाले"
+ "%1$s इंस्टॉल करण्याची प्रतिक्षा करत आहे"
+ "%1$s विजेट"
+ "होम स्क्रीनवर जोडा"
+ "आयटम येथे हलवा"
+ "आयटम मुख्य स्क्रीनवर जोडला"
+ "आयटम काढला"
+ "आयटम हलवा"
+ "पंक्ति %1$s स्तंभ %2$s मध्ये हलवा"
+ "%1$s स्थानावर हलवा"
+ "आवडत्या %1$s स्थानावर हलवा"
+ "आयटम हलविला"
+ "फोल्डरवर जोडा: %1$s"
+ "%1$s सह फोल्डरमध्ये जोडा"
+ "फोल्डरमध्ये आयटम जोडले"
+ "यासह फोल्डर तयार करा: %1$s"
+ "फोल्डर तयार केले"
+ "मुख्य स्क्रीनवर हलवा"
+ "आकार बदला"
+ "रूंदी वाढवा"
+ "उंची वाढवा"
+ "रुंदी कमी करा"
+ "उंची कमी करा"
+ "विजेटचा आकार रुंदी %1$s उंची %2$s मध्ये बदलला"
+ "शॉर्टकट"
+ "%2$s साठी %1$d शॉर्टकट"
+ "%3$sसाठी %1$d शॉर्टकट आणि %2$d सूचना"
+ "डिसमिस करा"
+ "सूचना डिसमिस केली"
+ "वैयक्तिक"
+ "कार्यालय"
+ "कार्य प्रोफाइल"
+ "कामाची अॅप्स येथे मिळवा"
+ "प्रत्येक कार्य अॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अॅक्सेससाठी अॅप्स तुमच्या होम स्क्रीनवर हलवा."
+ "तुमच्या संस्थेकडून व्यवस्थापित"
+ "सूचना आणि अॅप्स बंद आहेत"
+ "बंद करा"
+ "बंद केले"
+
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 751ad227ab..a297e06491 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -22,15 +22,15 @@
"Launcher3"
"कार्य"
- "अॅप स्थापित केलेला नाही."
+ "अॅप इंस्टॉल केलेला नाही."
"अॅप उपलब्ध नाही"
"डाउनलोड केलेला अॅप सुरक्षित मोड मध्ये अक्षम केला"
"विजेट सुरक्षित मोडमध्ये अक्षम झाले"
"शॉर्टकट उपलब्ध नाही"
"होम स्क्रीन"
- "सानुकूल क्रिया"
+ "कस्टम क्रिया"
"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."
- "एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा सानुकूल क्रिया वापरा."
+ "एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा कस्टम क्रिया वापरा."
"%1$d × %2$d"
"%1$d रूंद बाय %2$d उंच"
"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"
@@ -40,31 +40,40 @@
"\"%1$s\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"
"अधिक अॅप्स शोधा"
"सूचना"
+ "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."
+ "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."
"या मुख्य स्क्रीनवर आणखी जागा नाही."
"आवडीच्या ट्रे मध्ये आणखी जागा नाही"
"अॅप्स सूची"
+ "वैयक्तिक अॅप्स सूची"
+ "कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची"
"होम"
"काढा"
- "विस्थापित करा"
+ "अनइंस्टॉल करा"
"अॅप माहिती"
+ "इंस्टॉल करा"
"शॉर्टकट स्थापित करा"
"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अॅप ला अनुमती देते."
- "होम सेटिग्ज आणि शॉर्टकट वाचा"
+ "होम सेटिंग्ज आणि शॉर्टकट वाचा"
"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."
- "होम स्क्रीन सेटिंग्ज आणि शॉर्टकट लिहा"
+ "होम सेटिंग्ज आणि शॉर्टकट लिहा"
"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."
"%1$s ला फोन कॉल करण्याची अनुमती नाही"
"विजेट लोड करण्यात समस्या"
"सेटअप"
- "हा सिस्टम अॅप आहे आणि विस्थापित केला जाऊ शकत नाही."
+ "हा सिस्टम अॅप आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."
"अनामित फोल्डर"
"%1$s अक्षम केला आहे"
+
+ - %1$s, कडे %2$d सूचना आहे
+ - %1$s, कडे %2$d सूचना आहेत
+
"%2$d पैकी %1$d पृष्ठ"
"%2$d पैकी %1$d मुख्य स्क्रीन"
"नवीन मुख्य स्क्रीन पृष्ठ"
"फोल्डर उघडले, %1$d बाय %2$d"
"फोल्डर बंद करण्यासाठी टॅप करा"
- "पुनर्नामित करणे जतन करण्यासाठी टॅप करा"
+ "पुनर्नामित करणे सेव्ह करण्यासाठी टॅप करा"
"फोल्डर बंद"
"फोल्डरचे नाव बदलून %1$s असे ठेवले"
"फोल्डर: %1$s"
@@ -72,19 +81,19 @@
"वॉलपेपर"
"होम सेटिंग्ज"
"आपल्या प्रशासकाने अक्षम केले"
- "अवलोकन"
"मुख्यस्क्रीन फिरविण्यास अनुमती द्या"
"फोन फिरविला जातो तेव्हा"
- "वर्तमान प्रदर्शन सेटिंग फिरविण्यास परवानगी देत नाही"
"सूचना बिंदू"
"चालू"
"बंद"
"सूचनांच्या अॅक्सेसची आवश्यकता आहे"
"सूचना बिंदू दाखवण्यासाठी, %1$s साठी अॅप सूचना चालू करा"
"सेटिंग्ज बदला"
+ "सूचना बिंदू दाखवा"
"होम स्क्रीनवर आयकन जोडा"
"नवीन अॅप्ससाठी"
"चिन्हाचा आकार बदला"
+ "होम स्क्रीनवर"
"सिस्टमचे डीफॉल्ट वापरा"
"चौरस"
"गोलाकार चौरस"
@@ -94,11 +103,13 @@
"अज्ञात"
"काढा"
"शोधा"
- "हा अॅप स्थापित केलेला नाही"
- "या चिन्हासाठी अॅप स्थापित केलेला नाही. आपण ते काढू शकता किंवा अॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे स्थापित करू शकता."
+ "हा अॅप इंस्टॉल केलेला नाही"
+ "या चिन्हासाठी अॅप इंस्टॉल केलेला नाही. तुम्ही ते काढू शकता किंवा अॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे इंस्टॉल करू शकता."
"%1$s डाउनलोड होत आहे , %2$s पूर्ण झाले"
- "%1$s स्थापित करण्याची प्रतिक्षा करीत आहे"
+ "%1$s इंस्टॉल करण्याची प्रतिक्षा करत आहे"
"%1$s विजेट"
+ "विजेट सूची"
+ "विजेट सूची बंद केली"
"होम स्क्रीनवर जोडा"
"आयटम येथे हलवा"
"आयटम मुख्य स्क्रीनवर जोडला"
@@ -114,9 +125,6 @@
"यासह फोल्डर तयार करा: %1$s"
"फोल्डर तयार केले"
"मुख्य स्क्रीनवर हलवा"
- "स्क्रीन डावीकडे हलवा"
- "स्क्रीन उजवीकडे हलवा"
- "स्क्रीन हलविली"
"आकार बदला"
"रूंदी वाढवा"
"उंची वाढवा"
@@ -124,8 +132,16 @@
"उंची कमी करा"
"विजेटचा आकार रुंदी %1$s उंची %2$s मध्ये बदलला"
"शॉर्टकट"
- "%2$s साठी %1$d शॉर्टकट"
- "%3$sसाठी %1$d शॉर्टकट आणि %2$d सूचना"
+ "शॉर्टकट आणि सूचना"
"डिसमिस करा"
"सूचना डिसमिस केली"
+ "वैयक्तिक"
+ "कार्यालय"
+ "कार्य प्रोफाइल"
+ "कामाची अॅप्स येथे मिळवा"
+ "प्रत्येक कार्य अॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अॅक्सेससाठी अॅप्स तुमच्या होम स्क्रीनवर हलवा."
+ "तुमच्या संस्थेकडून व्यवस्थापित"
+ "सूचना आणि अॅप्स बंद आहेत"
+ "बंद करा"
+ "बंद केले"
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000000..3c223b6334
--- /dev/null
+++ b/res/values-ms-rMY/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Kerja"
+ "Apl tidak dipasang."
+ "Apl tidak tersedia"
+ "Apl yang dimuat turun dilumpuhkan dalam mod Selamat"
+ "Widget dilumpuhkan dalam mod Selamat"
+ "Pintasan tidak tersedia"
+ "Skrin utama"
+ "Tindakan tersuai"
+ "Sentuh & tahan untuk mengambil widget."
+ "Ketik dua kali & tahan untuk mengambil widget atau menggunakan tindakan tersuai"
+ "%1$d × %2$d"
+ "Lebar %1$d kali tinggi %2$d"
+ "Sentuh & tahan untuk meletakkan widget/ikon secara manual"
+ "Tambahkan secara automatik"
+ "Cari apl"
+ "Memuatkan apl…"
+ "Tiada apl yang ditemui sepadan dengan \"%1$s\""
+ "Cari lagi apl"
+ "Pemberitahuan"
+ "Sentuh & tahan untuk mengambil pintasan."
+ "Ketik dua kali & tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."
+ "Tiada lagi ruang pada skrin Laman Utama ini."
+ "Tiada ruang dalam dulang Kegemaran lagi"
+ "Senarai apl"
+ "Senarai apl peribadi"
+ "Senarai apl kerja"
+ "Laman Utama"
+ "Alih keluar"
+ "Nyahpasang"
+ "Maklumat apl"
+ "Pasang"
+ "pasang pintasan"
+ "Membenarkan apl menambah pintasan tanpa campur tangan pengguna."
+ "baca tetapan dan pintasan Laman Utama"
+ "Membenarkan apl membaca tetapan dan pintasan di Laman Utama."
+ "tulis tetapan dan pintasan Laman Utama"
+ "Membenarkan apl menukar tetapan dan pintasan di Laman Utama."
+ "%1$s tidak dibenarkan membuat panggilan telefon"
+ "Masalah memuatkan widget"
+ "Persediaan"
+ "Ini ialah apl sistem dan tidak boleh dinyahpasang."
+ "Folder Tanpa Nama"
+ "%1$s dilumpuhkan"
+
+ - %1$s, mempunyai %2$d pemberitahuan
+ - %1$s, mempunyai %2$d pemberitahuan
+
+ "Halaman %1$d daripada %2$d"
+ "Skrin Laman Utama %1$d daripada %2$d"
+ "Halaman skrin utama baharu"
+ "Folder dibuka, %1$d kali %2$d"
+ "Ketik untuk menutup folder"
+ "Ketik untuk menyimpan penamaan semula"
+ "Folder ditutup"
+ "Folder dinamakan semula kepada %1$s"
+ "Folder: %1$s"
+ "Widget"
+ "Kertas dinding"
+ "Tetapan laman utama"
+ "Dilumpuhkan oleh pentadbir anda"
+ "Benarkan putaran Skrin Utama"
+ "Apabila telefon diputar"
+ "Titik pemberitahuan"
+ "Hidup"
+ "Mati"
+ "Akses pemberitahuan diperlukan"
+ "Untuk menunjukkan Titik Pemberitahuan, hidupkan pemberitahuan apl untuk %1$s"
+ "Tukar tetapan"
+ "Tunjukkan titik pemberitahuan"
+ "Tambahkan ikon pada Skrin Utama"
+ "Untuk apl baharu"
+ "Tukar bentuk ikon"
+ "pada Skrin Utama"
+ "Gunakan lalai sistem"
+ "Segi empat sama"
+ "Segi empat berbucu bulat"
+ "Bulatan"
+ "Titisan air mata"
+ "Menggunakan perubahan bentuk ikon"
+ "Tidak diketahui"
+ "Alih keluar"
+ "Carian"
+ "Apl ini tidak dipasang"
+ "Apl untuk ikon ini tidak dipasang. Anda boleh mengalih keluar atau mencari dan memasang apl itu secara manual."
+ "%1$s memuat turun, %2$s selesai"
+ "%1$s menunggu untuk dipasang"
+ "Widget %1$s"
+ "Tambahkan pada Skrin Utama"
+ "Alihkan item ke sini"
+ "Item ditambahkan pada skrin utama"
+ "Item dialih keluar"
+ "Alihkan Item"
+ "Alihkan ke baris %1$s lajur %2$s"
+ "Alihkan ke kedudukan %1$s"
+ "Alihkan ke kedudukan kegemaran %1$s"
+ "Item dialihkan"
+ "Tambahkan pada folder: %1$s"
+ "Tambahkan pada folder dengan %1$s"
+ "Item ditambahkan pada folder"
+ "Buat folder dengan: %1$s"
+ "Folder dibuat"
+ "Alihkan ke Skrin Utama"
+ "Ubah saiz"
+ "Tambahkan kelebaran"
+ "Tambahkan ketinggian"
+ "Kurangkan kelebaran"
+ "Kurangkan ketinggian"
+ "Saiz widget diubah menjadi %1$s lebar %2$s tinggi"
+ "Pintasan"
+ "%1$d pintasan untuk %2$s"
+ "%1$d pintasan dan %2$d pemberitahuan untuk %3$s"
+ "Ketepikan"
+ "Pemberitahuan diketepikan"
+ "Peribadi"
+ "Kerja"
+ "Profil kerja"
+ "Temui apl kerja di sini"
+ "Setiap apl kerja terdapat lencana dan dilindungi oleh organisasi anda. Alihkan apl ke Skrin Utama untuk akses yang lebih mudah."
+ "Diurus oleh organisasi anda"
+ "Pemberitahuan dan apl dimatikan"
+ "Tutup"
+ "Ditutup"
+
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index f94b167a69..71047fbc50 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -40,13 +40,18 @@
"Tiada apl yang ditemui sepadan dengan \"%1$s\""
"Cari lagi apl"
"Pemberitahuan"
+ "Sentuh & tahan untuk mengambil pintasan."
+ "Ketik dua kali & tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."
"Tiada lagi ruang pada skrin Laman Utama ini."
"Tiada ruang dalam dulang Kegemaran lagi"
"Senarai apl"
+ "Senarai apl peribadi"
+ "Senarai apl kerja"
"Laman Utama"
"Alih keluar"
"Nyahpasang"
"Maklumat apl"
+ "Pasang"
"pasang pintasan"
"Membenarkan apl menambah pintasan tanpa campur tangan pengguna."
"baca tetapan dan pintasan Laman Utama"
@@ -59,6 +64,10 @@
"Ini ialah apl sistem dan tidak boleh dinyahpasang."
"Folder Tanpa Nama"
"%1$s dilumpuhkan"
+
+ - %1$s, mempunyai %2$d pemberitahuan
+ - %1$s, mempunyai %2$d pemberitahuan
+
"Halaman %1$d daripada %2$d"
"Skrin Laman Utama %1$d daripada %2$d"
"Halaman skrin utama baharu"
@@ -72,19 +81,19 @@
"Kertas dinding"
"Tetapan laman utama"
"Dilumpuhkan oleh pentadbir anda"
- "Ikhtisar"
"Benarkan putaran Skrin Utama"
"Apabila telefon diputar"
- "Tetapan Paparan semasa tidak membenarkan putaran"
"Titik pemberitahuan"
"Hidup"
"Mati"
"Akses pemberitahuan diperlukan"
"Untuk menunjukkan Titik Pemberitahuan, hidupkan pemberitahuan apl untuk %1$s"
"Tukar tetapan"
+ "Tunjukkan titik pemberitahuan"
"Tambahkan ikon pada Skrin Utama"
"Untuk apl baharu"
"Tukar bentuk ikon"
+ "pada Skrin Utama"
"Gunakan lalai sistem"
"Segi empat sama"
"Segi empat berbucu bulat"
@@ -99,6 +108,8 @@
"%1$s memuat turun, %2$s selesai"
"%1$s menunggu untuk dipasang"
"Widget %1$s"
+ "Senarai widget"
+ "Senarai widget ditutup"
"Tambahkan pada Skrin Utama"
"Alihkan item ke sini"
"Item ditambahkan pada skrin utama"
@@ -114,9 +125,6 @@
"Buat folder dengan: %1$s"
"Folder dibuat"
"Alihkan ke Skrin Utama"
- "Alihkan skrin ke kiri"
- "Alihkan skrin ke kanan"
- "Skrin dialihkan"
"Ubah saiz"
"Tambahkan kelebaran"
"Tambahkan ketinggian"
@@ -124,8 +132,16 @@
"Kurangkan ketinggian"
"Saiz widget diubah menjadi %1$s lebar %2$s tinggi"
"Pintasan"
- "%1$d pintasan untuk %2$s"
- "%1$d pintasan dan %2$d pemberitahuan untuk %3$s"
+ "Pintasan dan pemberitahuan"
"Ketepikan"
"Pemberitahuan diketepikan"
+ "Peribadi"
+ "Kerja"
+ "Profil kerja"
+ "Temui apl kerja di sini"
+ "Setiap apl kerja terdapat lencana dan dilindungi oleh organisasi anda. Alihkan apl ke Skrin Utama untuk akses yang lebih mudah."
+ "Diurus oleh organisasi anda"
+ "Pemberitahuan dan apl dimatikan"
+ "Tutup"
+ "Ditutup"
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
new file mode 100644
index 0000000000..59ac4cad35
--- /dev/null
+++ b/res/values-my-rMM/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "ဖွင့်တင်စက်၃"
+
+ "အလုပ်"
+ "အက်ပ်မထည့်သွင်းထားပါ"
+ "အက်ပ်လက်လှမ်း မမှီပါ"
+ "ဒေါင်းလုဒ် အက်ပ်ကို လုံခြုံရေး မုဒ်ထဲမှာ ပိတ်ထား"
+ "လုံခြုံရေး မုဒ်ထဲမှာ ဝီဂျက်များကို ပိတ်ထား"
+ "ဖြတ်လမ်း မရနိုင်ပါ"
+ "ပင်မစာမျက်နှာ"
+ "စိတ်ကြိုက် လုပ်ဆောင်ချက်များ"
+ "ဝဒ်ဂျက်တစ်ခုကို ကောက်ယူရန် ဖိနှိပ်ထားပါ"
+ "ဝစ်ဂျက်တစ်ခုကိုရယူရန် သို့မဟုတ် စိတ်ကြိုက်လုပ်ဆောင်မှုများကို အသုံးပြုရန် နှစ်ချက်တို့ပြီး ကိုင်ထားပါ။"
+ "%1$d × %2$d"
+ "အလျား %1$d နှင့် အမြင့် %2$d"
+ "ကိုယ်တိုင်ထည့်ရန် ထိထားပါ"
+ "အလိုအလျောက် ထည့်ရန်"
+ "ရှာဖွေမှု အက်ပ်များ"
+ "အက်ပ်များကို ဖွင့်နေသည်…"
+ "\"%1$s\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"
+ "နောက်ထပ် အက်ပ်များကို ရှာပါ"
+ "အကြောင်းကြားချက်များ"
+ "ဖြတ်လမ်းလင့်ခ်တစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ။"
+ "ဖြတ်လမ်းလင့်ခ်ကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"
+ "ဤပင်မမျက်နှာစာတွင် နေရာလွတ် မကျန်တော့ပါ"
+ "အနှစ်သက်ဆုံးများ ထားရာတွင် နေရာလွတ် မကျန်တော့ပါ"
+ "အက်ပ်စာရင်း"
+ "တစ်ကိုယ်ရေသုံး အက်ပ်စာရင်း"
+ "အလုပ်သုံး အက်ပ်စာရင်း"
+ "ပင်မစာမျက်နှာ"
+ "ဖယ်ရှားမည်"
+ "ဖယ်ထုတ်မည်"
+ "အက်ပ်အချက်အလက်များ"
+ "ထည့်သွင်းရန်"
+ "အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း"
+ "အသုံးပြုသူ လုပ်ဆောင်မှုမရှိပဲ အပ်ပလီကေးရှင်းကို အတိုကောက်မှတ်သားမှုများ ပြုလုပ်ခွင့် ပေးခြင်း"
+ "ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ဖတ်ခြင်း"
+ "ပင်မမျက်နှာစာတွင်ရှိသော အပြင်အဆင်နှင့် အတိုကောက်မှတ်သားမှုများကို အပ်ပလီကေးရှင်းအား ဖတ်ခွင့်ပြုခြင်း"
+ "ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ရေးသားခြင်း"
+ "ပင်မမျက်နှာစာတွင် ရှိသော အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများ ကို အပ်ပလီကေးရှင်းအား ပြောင်းခွင့်ပြုခြင်း"
+ "%1$sသည် ဖုန်းခေါ်ဆိုခွင့် မရှိပါ"
+ "ဝဒ်ဂျက် တင်ရာတွင် ပြသနာ ရှိပါသည်"
+ "စဖွင့်သတ်မှတ်ရန်"
+ "ဤအပ်ပလီကေးရှင်းမှာ စစ်စတန်ပိုင်းဆိုင်ရာ အပ်ပလီကေးရှင်းဖြစ်ပါသည်။ ထုတ်ပစ်၍ မရပါ"
+ "အမည်မရှိအကန့်"
+ "%1$s ကို ပိတ်ထားသည်"
+
+ - %1$s တွင် အကြောင်းကြားချက် %2$d ခု ရှိသည်
+ - %1$s တွင် အကြောင်းကြားချက် %2$d ခု ရှိသည်
+
+ "စာမျက်နှာ %1$d မှ %2$d"
+ "ပင်မစာမျက်နှာ %1$d မှ %2$d"
+ "ပင်မမျက်နှာပြင် စာမျက်နှာသစ်"
+ "ဖွင့်ထားသောအကန့်, %1$d နှင့် %2$d"
+ "ဖိုင်တွဲကို ပိတ်ရန် တို့ပါ"
+ "အမည်ပြောင်းခြင်းကို သိမ်းဆည်းရန် တို့ပါ"
+ "ပိတ်ထားသောအကန့်"
+ "ပြောင်းလဲလိုက်သော အကန့်အမည် %1$s"
+ "အကန့်အမည်: %1$s"
+ "ဝိဂျက်များ"
+ "နောက်ခံများ"
+ "ပင်မဆက်တင်များ"
+ "သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"
+ "ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"
+ "ဖုန်းကိုလှည့်ထားစဉ်"
+ "အကြောင်းကြားချက်အမှတ်အသားများ"
+ "ဖွင့်ထားသည်"
+ "ပိတ်ထားသည်"
+ "အကြောင်းကြားချက် အသုံးပြုခွင့် လိုအပ်သည်"
+ "အကြောင်းကြားချက် အစက်များကို ပြသရန် %1$s အတွက် အက်ပ်အကြောင်းကြားချက်များကို ဖွင့်ပါ"
+ "ဆက်တင်များ ပြောင်းရန်"
+ "အကြောင်းကြားချက် အမှတ်အသားများကို ပြရန်"
+ "ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"
+ "အက်ပ်အသစ်များအတွက်"
+ "သင်္ကေတပုံစံကို ပြောင်းရန်"
+ "\'ပင်မမျက်နှာပြင်\' ပေါ်တွင်"
+ "စနစ်၏ မူရင်းပုံကို အသုံးပြုရန်"
+ "လေးထောင့်"
+ "စတုရန်းမကျ စက်ဝိုင်းမကျပုံ"
+ "စက်ဝိုင်း"
+ "မျက်ရည်စက်ပုံ"
+ "သင်္ကေတပုံစံကို ပြောင်းလဲနေသည်"
+ "မသိရ"
+ "ဖယ်ရှားရန်"
+ "ရှာဖွေရန်"
+ "အက်ပ်မတပ်ဆင်ရသေးပါ"
+ "ဤအိုင်ကွန်အတွက် အက်ပ်အားမထည့်သွင်းထားပါ။ You can remove it, or search for the အက်ပ်and install it manually."
+ "%1$s ဒေါင်းလုဒ်လုပ်နေသည်၊ %2$s ပြီးပါပြီ"
+ "%1$s ကိုထည့်သွင်းရန်စောင့်နေသည်"
+ "%1$s ဝိဂျက်များ"
+ "ပင်မမျက်နှာစာသို့ ထည့်ပါ"
+ "၎င်းအား ဤသို့ ရွှေ့ပါ"
+ "ပင်မ ဖန်မျက်နှာပြင်သို့ ထည့်ပြီး၏"
+ "၎င်းအား ဖယ်ရှားပြီး၏"
+ "၎င်းအား ရွှေ့ပါ"
+ "အတန်း %1$s အတိုင် %2$s သို့ ရွှေ့ပါ"
+ "%1$s သို့ နေရာရွှေ့ပါ"
+ "စိတ်ကြိုက်နေရာ %1$s သို့ ရွှေ့ပါ"
+ "၎င်းအားရွှေ့ပြီး"
+ "ဖိုလ်ဒါသို့ ထည့်ရန်- %1$s"
+ "%1$s အမည်ရှိ ဖိုလ်ဒါသို့ ထည့်ပြီး၏"
+ "ဖိုလ်ဒါသို့ ထည့်ပြီး"
+ "ဖိုလ်ဒါ ပြုလုပ်ရန်- %1$s"
+ "ဖိုလ်ဒါ ပြုလုပ်ပြီး"
+ "ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ"
+ "အရွယ်အစားပြောင်းပါ"
+ "အကျယ်အား တိုးပါ"
+ "အမြင့်အား တိုးပါ"
+ "အကျယ်အား လျှော့ပါ"
+ "အမြင့်အား လျှော့ပါ"
+ "Widget အား အကျယ် %1$s အမြင့် %2$s အရွယ်အစားပြန်လည်ချိန်ညှိပြီး၏"
+ "ဖြတ်လမ်းများ"
+ "%2$s အတွက် အမြန်နည်း %1$d ခု"
+ "%3$s အတွက် ဖြတ်လမ်းလင့်ခ် %1$d နှင့် အကြောင်းကြားချက် %2$d ခု"
+ "ပယ်ရန်"
+ "အသိပေးချက်ကို ဖယ်ထုတ်ပြီးပါပြီ"
+ "ကိုယ်ပိုင်"
+ "အလုပ်"
+ "အလုပ်ပရိုဖိုင်"
+ "အလုပ်အက်ပ်များကို ဤနေရာတွင်ရှာဖွေပါ"
+ "အလုပ်အက်ပ်တိုင်းတွင် တံဆိပ် တစ်ခုစီရှိပြီး သင်၏ အဖွဲ့အစည်းက လုံခြုံအောင် ထားရှိပါသည်။ အသုံးပြုရ ပိုမိုလွယ်ကူစေရန် အက်ပ်များကို သင်၏ ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ။"
+ "သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"
+ "အကြောင်းကြားချက်များနှင့် အက်ပ်များကို ပိတ်ထားသည်"
+ "ပိတ်ရန်"
+ "ပိတ်ထားသည်"
+
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 74574b9b23..6c261853a4 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"
"နောက်ထပ် အက်ပ်များကို ရှာပါ"
"အကြောင်းကြားချက်များ"
+ "ဖြတ်လမ်းလင့်ခ်တစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ။"
+ "ဖြတ်လမ်းလင့်ခ်ကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"
"ဤပင်မမျက်နှာစာတွင် နေရာလွတ် မကျန်တော့ပါ"
"အနှစ်သက်ဆုံးများ ထားရာတွင် နေရာလွတ် မကျန်တော့ပါ"
"အက်ပ်စာရင်း"
+ "တစ်ကိုယ်ရေသုံး အက်ပ်စာရင်း"
+ "အလုပ်သုံး အက်ပ်စာရင်း"
"ပင်မစာမျက်နှာ"
"ဖယ်ရှားမည်"
"ဖယ်ထုတ်မည်"
"အက်ပ်အချက်အလက်များ"
+ "ထည့်သွင်းရန်"
"အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း"
"အသုံးပြုသူ လုပ်ဆောင်မှုမရှိပဲ အပ်ပလီကေးရှင်းကို အတိုကောက်မှတ်သားမှုများ ပြုလုပ်ခွင့် ပေးခြင်း"
"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ဖတ်ခြင်း"
@@ -59,6 +64,10 @@
"ဤအပ်ပလီကေးရှင်းမှာ စစ်စတန်ပိုင်းဆိုင်ရာ အပ်ပလီကေးရှင်းဖြစ်ပါသည်။ ထုတ်ပစ်၍ မရပါ"
"အမည်မရှိအကန့်"
"%1$s ကို ပိတ်ထားသည်"
+
+ - %1$s တွင် အကြောင်းကြားချက် %2$d ခု ရှိသည်
+ - %1$s တွင် အကြောင်းကြားချက် %2$d ခု ရှိသည်
+
"စာမျက်နှာ %1$d မှ %2$d"
"ပင်မစာမျက်နှာ %1$d မှ %2$d"
"ပင်မမျက်နှာပြင် စာမျက်နှာသစ်"
@@ -72,19 +81,19 @@
"နောက်ခံများ"
"ပင်မဆက်တင်များ"
"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"
- "ခြုံငုံသုံးသပ်ချက်"
"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"
"ဖုန်းကိုလှည့်ထားစဉ်"
- "လက်ရှိ မြင်ကွင်းဆက်တင်တွင် မြင်ကွင်းကို လှည့်ခွင့်မပေးပါ"
"အကြောင်းကြားချက်အမှတ်အသားများ"
"ဖွင့်ထားသည်"
"ပိတ်ထားသည်"
"အကြောင်းကြားချက် အသုံးပြုခွင့် လိုအပ်သည်"
"အကြောင်းကြားချက် အစက်များကို ပြသရန် %1$s အတွက် အက်ပ်အကြောင်းကြားချက်များကို ဖွင့်ပါ"
"ဆက်တင်များ ပြောင်းရန်"
+ "အကြောင်းကြားချက် အမှတ်အသားများကို ပြရန်"
"ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"
"အက်ပ်အသစ်များအတွက်"
"သင်္ကေတပုံစံကို ပြောင်းရန်"
+ "\'ပင်မမျက်နှာပြင်\' ပေါ်တွင်"
"စနစ်၏ မူရင်းပုံကို အသုံးပြုရန်"
"လေးထောင့်"
"စတုရန်းမကျ စက်ဝိုင်းမကျပုံ"
@@ -99,6 +108,8 @@
"%1$s ဒေါင်းလုဒ်လုပ်နေသည်၊ %2$s ပြီးပါပြီ"
"%1$s ကိုထည့်သွင်းရန်စောင့်နေသည်"
"%1$s ဝိဂျက်များ"
+ "ဝိဂျက်စာရင်း"
+ "ဝိဂျက်စာရင်းကို ပိတ်ထားသည်"
"ပင်မမျက်နှာစာသို့ ထည့်ပါ"
"၎င်းအား ဤသို့ ရွှေ့ပါ"
"ပင်မ ဖန်မျက်နှာပြင်သို့ ထည့်ပြီး၏"
@@ -114,9 +125,6 @@
"ဖိုလ်ဒါ ပြုလုပ်ရန်- %1$s"
"ဖိုလ်ဒါ ပြုလုပ်ပြီး"
"ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ"
- "မျက်နှာပြင် ဘယ်ဘက်သို့ ရွှေ့ပါ"
- "မျက်နှာပြင် ညာဘက်သို့ ရွှေ့ပါ"
- "ဖန်မျက်နှာပြင် ပြောင်းရွှေ့ပြီး၏"
"အရွယ်အစားပြောင်းပါ"
"အကျယ်အား တိုးပါ"
"အမြင့်အား တိုးပါ"
@@ -124,8 +132,16 @@
"အမြင့်အား လျှော့ပါ"
"Widget အား အကျယ် %1$s အမြင့် %2$s အရွယ်အစားပြန်လည်ချိန်ညှိပြီး၏"
"ဖြတ်လမ်းများ"
- "%2$s အတွက် အမြန်နည်း %1$d ခု"
- "%3$s အတွက် ဖြတ်လမ်းလင့်ခ် %1$d နှင့် အကြောင်းကြားချက် %2$d ခု"
+ "ဖြတ်လမ်းလင့်ခ်နှင့် အကြောင်းကြားချက်များ"
"ပယ်ရန်"
"အသိပေးချက်ကို ဖယ်ထုတ်ပြီးပါပြီ"
+ "ကိုယ်ပိုင်"
+ "အလုပ်"
+ "အလုပ်ပရိုဖိုင်"
+ "အလုပ်အက်ပ်များကို ဤနေရာတွင်ရှာဖွေပါ"
+ "အလုပ်အက်ပ်တိုင်းတွင် တံဆိပ် တစ်ခုစီရှိပြီး သင်၏ အဖွဲ့အစည်းက လုံခြုံအောင် ထားရှိပါသည်။ အသုံးပြုရ ပိုမိုလွယ်ကူစေရန် အက်ပ်များကို သင်၏ ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ။"
+ "သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"
+ "အကြောင်းကြားချက်များနှင့် အက်ပ်များကို ပိတ်ထားသည်"
+ "ပိတ်ရန်"
+ "ပိတ်ထားသည်"
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 65247c168d..67a912b08a 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -40,13 +40,18 @@
"Fant ingen apper som samsvarer med «%1$s»"
"Søk etter flere apper"
"Varsler"
+ "Trykk og hold for å velge en snarvei."
+ "Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger."
"Denne startsiden er full."
"Favoritter-skuffen er full"
"App-liste"
+ "Personlige apper-liste"
+ "Jobbapper-liste"
"Startside"
"Fjern"
"Avinstaller"
"Info om appen"
+ "Installer"
"installere snarveier"
"Gir apper tillatelse til å legge til snarveier uten innblanding fra brukeren."
"lese startsideinnstillinger og -snarveier"
@@ -59,6 +64,10 @@
"Dette er en systemapp som ikke kan avinstalleres."
"Mappe uten navn"
"Slo av %1$s"
+
+ - %1$s har %2$d varsler
+ - %1$s har %2$d varsel
+
"Side %1$d av %2$d"
"Startside %1$d av %2$d"
"Ny side på startskjermen"
@@ -72,19 +81,19 @@
"Bakgrunner"
"Startsideinnstillinger"
"Administratoren har slått av funksjonen"
- "Oversikt"
"Tillat rotasjon av startskjermen"
"Når telefonen roteres"
- "Med den nåværende skjerminnstillingen støttes ikke rotasjon"
"Varselsprikker"
"På"
"Av"
"Tilgang til varsler er nødvendig"
"Slå på appvarsler for %1$s for å vise varselsprikker"
"Endre innstillingene"
+ "Vis varselsprikker"
"Legg til ikon på startsiden"
"For nye apper"
"Endre formen på ikonet"
+ "på startskjermen"
"Bruk systemstandard"
"Kvadrat"
"Superellipse"
@@ -99,6 +108,8 @@
"Laster ned %1$s, %2$s er fullført"
"Venter på å installere %1$s"
"%1$s-moduler"
+ "Modulliste"
+ "Modullisten er lukket"
"Legg til på startskjermen"
"Flytt elementet hit"
"Elementet er lagt til på startskjermen"
@@ -114,9 +125,6 @@
"Opprett mappe med: %1$s"
"Mappen er opprettet"
"Flytt til startskjermen"
- "Flytt skjermen til venstre"
- "Flytt skjermen til høyre"
- "Skjermen er flyttet"
"Endre størrelse"
"Øk bredden"
"Øk høyden"
@@ -124,8 +132,16 @@
"Reduser høyden"
"Størrelsen på modulen er endret til bredde %1$s og høyde %2$s"
"Snarveier"
- "%1$d snarveier for %2$s"
- "%1$d snarveier og %2$d varsler for %3$s"
+ "Snarveier og varsler"
"Avvis"
"Varselet ble avvist"
+ "Personlig"
+ "Jobb"
+ "Jobbprofil"
+ "Finn jobbapper her"
+ "Alle jobbapper har et merke og sikres av organisasjonen din. Flytt apper til startskjermen for å gjøre det enklere å finne dem."
+ "Administreres av organisasjonen din"
+ "Varsler og apper er slått av"
+ "Lukk"
+ "Lukket"
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000000..a8a64f1bbc
--- /dev/null
+++ b/res/values-ne-rNP/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "कार्य"
+ "अनुप्रयोग स्थापित छैन।"
+ "अनुप्रयोग उपलब्ध छैन"
+ "सुरक्षित मोडमा डाउनलोड गरेको अनुप्रयोग अक्षम गरिएको छ"
+ "सुरक्षित मोडमा विगेटहरू अक्षम गरियो"
+ "सर्टकट उपलब्ध छैन"
+ "गृह स्क्रिन"
+ "आफू अनुकूलका कारबाहीहरू"
+ "एउटा विजेटलाई टिप्नको लागि टच गरेर होल्ड गर्नुहोस्।"
+ "विजेटलाई छान्न वा आफू अनुकूल कार्यहरू प्रयोग गर्न डबल ट्याप गरी होल्ड गर्नुहोस्।"
+ "%1$d × %2$d"
+ "%1$d चौडाइ गुणा %2$d उचाइ"
+ "म्यानुअल तरिकाले थप्न छुनुहोस् र थिची राख्नुहोस्"
+ "स्वतः थप्नुहोस्"
+ "खोजसम्बन्धी अनुप्रयोगहरू"
+ "अनुप्रयोगहरू लोड गर्दै…"
+ "\"%1$s\" सँग मिल्दो कुनै अनुप्रयोग भेटिएन"
+ "थप अनुप्रयोगहरू खोज्नुहोस्"
+ "सूचनाहरू"
+ "कुनै सर्टकट छनौट गर्न छोइराख्नुहोस्।"
+ "कुनै सर्टकट छनौट गर्न वा रोजेका कारबाहीहरू प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"
+ "यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"
+ "मनपर्ने ट्रे अब कुनै ठाँउ छैन"
+ "अनुप्रयोगको सूची"
+ "व्यक्तिगत अनुप्रयोगहरूको सूची"
+ "कार्यसम्बन्धी अनुप्रयोगहरूको सूची"
+ "गृह"
+ "हटाउनुहोस्"
+ "विस्थापित गर्नुहोस्"
+ "अनुप्रयोग जानकारी"
+ "स्थापना गर्नुहोस्"
+ "सर्टकट स्थापना गर्नेहोस्"
+ "प्रयोगकर्ताको हस्तक्षेप बिना एउटा अनुप्रयोगलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"
+ "गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"
+ "गृहमा एउटा अनुप्रयोगलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"
+ "गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"
+ "गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"
+ "%1$s ले फोन कलहरू गर्न अनुमति छैन"
+ "समस्या लोडिङ गर्ने विजेट"
+ "सेटअप"
+ "यो प्रणाली अनुप्रयोग हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"
+ "बेनाम फोल्डर"
+ "असक्षम पारिएको %1$s"
+
+ - %1$s, यसमा %2$d सूचनाहरू छन्
+ - %1$s, यसमा %2$d सूचना छ
+
+ "पृष्ठ %2$d को %1$d"
+ "गृह स्क्रिन %1$d को %2$d"
+ "नयाँ गृह स्क्रिन पृष्ठ"
+ "फोल्डर खुल्यो %1$d बाट %2$d"
+ "फोल्डरलाई बन्द गर्न ट्याप गर्नुहोस्"
+ "पुनःनामाकरणलाई सुरक्षित गर्न ट्याप गर्नुहोस्"
+ "फोल्डर बन्द भयो"
+ "फोल्डर %1$s मा पुनःनामाकरण गरियो।"
+ "फोल्डर: %1$s"
+ "विजेटहरू"
+ "वालपेपरहरु"
+ "गृहपृष्ठका सेटिङहरू"
+ "तपाईँको प्रशासकद्वारा असक्षम गरिएको"
+ "गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"
+ "फोनलाई घुमाइँदा"
+ "सूचनाको प्रतीक जनाउने थोप्लोहरू"
+ "सक्रिय छ"
+ "निष्क्रिय छ"
+ "सूचनासम्बन्धी पहुँच आवश्यक हुन्छ"
+ "सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउन %1$s को अनुप्रयोगसम्बन्धी सूचनाहरूलाई सक्रिय गर्नुहोस्"
+ "सेटिङहरू बदल्नुहोस्"
+ "सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउनुहोस्"
+ "गृह स्क्रिनमा आइकन थप्नुहोस्"
+ "नयाँ अनुप्रयोगका लागि"
+ "आइकनको आकार परिवर्तन गर्नुहोस्"
+ "गृह स्क्रिनमा"
+ "प्रणालीको पूर्वनिर्धारित सेटिङ प्रयोग गर्नुहोस्"
+ "वर्ग"
+ "वर्गाकार वृत्त"
+ "वृत्त"
+ "आँसुको थोपा"
+ "आइकनको आकारमा गरिएका परिवर्तनहरू लागू गरिँदैछन्"
+ "अज्ञात"
+ "हटाउनुहोस्"
+ "खोजी गर्नुहोस्"
+ "यो अनुप्रयोग स्थापित छैन"
+ "यो प्रतिमाका लागि अनुप्रयोगलाई स्थापना गरिएको छैन। तपाईं यसलाई हटाउन, वा अनुप्रयोग खोजी र स्वयं यो स्थापित गर्न सक्नुहुन्छ।"
+ "%1$s डाउनलोड गर्दै, %2$s सम्पन्न"
+ "%1$s स्थापना गर्न प्रतीक्षा गर्दै"
+ "%1$s विजेटहरू"
+ "गृह स्क्रिनमा थप्नुहोस्"
+ "वस्तु यहाँ सार्नुहोस्"
+ "वस्तु गृह स्क्रिनमा थपियो"
+ "वस्तु हटाइयो"
+ "वस्तु सार्नुहोस्"
+ "पङ्क्ति %1$s स्तम्भ %2$s मा सार्नुहोस्"
+ "स्थिति %1$s मा सार्नुहोस्"
+ "मनपर्ने स्थिति %1$s मा सार्नुहोस्"
+ "वस्तु सारियो"
+ "फोल्डर: %1$s मा थप्नुहोस्"
+ "फोल्डरमा %1$s सँग थप्नुहोस्"
+ "वस्तु फोल्डरमा थपियो"
+ "%1$s: मार्फत फोल्डर सिर्जना गर्नुहोस्"
+ "फोल्डर सिर्जना गरियो"
+ "गृह स्क्रिनमा सार्नुहोस्"
+ "पुनःआकार मिलाउनुहोस्"
+ "चौडाइ बढाउनुहोस्"
+ "उँचाइ बढाउनुहोस्"
+ "चौडाइ घटाउनुहोस्"
+ "उँचाइ घटाउनुहोस्"
+ "विजेट चौडाइ %1$s उचाइ %2$s मा पुनः आकार मिलाइयो"
+ "सर्टकटहरू"
+ "%2$s का %1$d सर्टकटहरू"
+ "%3$s का %1$d सर्टकट र %2$d सूचनाहरू"
+ "खारेज गर्नुहोस्"
+ "सूचना खारेज गरियो"
+ "व्यक्तिगत"
+ "कार्यसम्बन्धी"
+ "कार्य प्रोफाइल"
+ "कार्यसम्बन्धी अनुप्रयोगहरू यहाँ प्राप्त गर्नुहोस्"
+ "कार्यसम्बन्धी प्रत्येक अनुप्रयोगमा एउटा ब्याज छ र तपाईंको संगठनले यसलाई सुरक्षित राखेको छ । अझ सजिलो गरी पहुँच राख्नका लागि अनुप्रयोगहरूलाई आफ्नो गृहस्क्रिनमा सार्नुहोस्।"
+ "तपाईंको सङ्गठनले व्यवस्थापन गरेको"
+ "सूचना र अनुप्रयोगहरू निष्क्रिय छन्"
+ "बन्द गर्नुहोस्"
+ "बन्द गरियो"
+
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 904dad45e2..50c427969c 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" सँग मिल्दो कुनै अनुप्रयोग भेटिएन"
"थप अनुप्रयोगहरू खोज्नुहोस्"
"सूचनाहरू"
+ "कुनै सर्टकट छनौट गर्न छोइराख्नुहोस्।"
+ "कुनै सर्टकट छनौट गर्न वा रोजेका कारबाहीहरू प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"
"यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"
"मनपर्ने ट्रे अब कुनै ठाँउ छैन"
"अनुप्रयोगको सूची"
+ "व्यक्तिगत अनुप्रयोगहरूको सूची"
+ "कार्यसम्बन्धी अनुप्रयोगहरूको सूची"
"गृह"
"हटाउनुहोस्"
"विस्थापित गर्नुहोस्"
"अनुप्रयोग जानकारी"
+ "स्थापना गर्नुहोस्"
"सर्टकट स्थापना गर्नेहोस्"
"प्रयोगकर्ताको हस्तक्षेप बिना एउटा अनुप्रयोगलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"
"गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"
@@ -59,6 +64,10 @@
"यो प्रणाली अनुप्रयोग हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"
"बेनाम फोल्डर"
"असक्षम पारिएको %1$s"
+
+ - %1$s, यसमा %2$d सूचनाहरू छन्
+ - %1$s, यसमा %2$d सूचना छ
+
"पृष्ठ %2$d को %1$d"
"गृह स्क्रिन %1$d को %2$d"
"नयाँ गृह स्क्रिन पृष्ठ"
@@ -72,19 +81,19 @@
"वालपेपरहरु"
"गृहपृष्ठका सेटिङहरू"
"तपाईँको प्रशासकद्वारा असक्षम गरिएको"
- "परिदृश्य"
"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"
"फोनलाई घुमाइँदा"
- "हालको प्रदर्शन सम्बन्धी सेटिङले घुमाउने सुविधालाई अनुमति दिँदैन"
"सूचनाको प्रतीक जनाउने थोप्लोहरू"
"सक्रिय छ"
"निष्क्रिय छ"
"सूचनासम्बन्धी पहुँच आवश्यक हुन्छ"
"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउन %1$s को अनुप्रयोगसम्बन्धी सूचनाहरूलाई सक्रिय गर्नुहोस्"
"सेटिङहरू बदल्नुहोस्"
+ "सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउनुहोस्"
"गृह स्क्रिनमा आइकन थप्नुहोस्"
"नयाँ अनुप्रयोगका लागि"
"आइकनको आकार परिवर्तन गर्नुहोस्"
+ "गृह स्क्रिनमा"
"प्रणालीको पूर्वनिर्धारित सेटिङ प्रयोग गर्नुहोस्"
"वर्ग"
"वर्गाकार वृत्त"
@@ -99,6 +108,10 @@
"%1$s डाउनलोड गर्दै, %2$s सम्पन्न"
"%1$s स्थापना गर्न प्रतीक्षा गर्दै"
"%1$s विजेटहरू"
+
+
+
+
"गृह स्क्रिनमा थप्नुहोस्"
"वस्तु यहाँ सार्नुहोस्"
"वस्तु गृह स्क्रिनमा थपियो"
@@ -114,9 +127,6 @@
"%1$s: मार्फत फोल्डर सिर्जना गर्नुहोस्"
"फोल्डर सिर्जना गरियो"
"गृह स्क्रिनमा सार्नुहोस्"
- "स्क्रिनलाई बायाँ सार्नुहोस्"
- "स्क्रिनलाई दायाँ सार्नुहोस्"
- "स्क्रिन सारियो"
"पुनःआकार मिलाउनुहोस्"
"चौडाइ बढाउनुहोस्"
"उँचाइ बढाउनुहोस्"
@@ -124,8 +134,16 @@
"उँचाइ घटाउनुहोस्"
"विजेट चौडाइ %1$s उचाइ %2$s मा पुनः आकार मिलाइयो"
"सर्टकटहरू"
- "%2$s का %1$d सर्टकटहरू"
- "%3$s का %1$d सर्टकट र %2$d सूचनाहरू"
+ "सर्टकट तथा सूचनाहरू"
"खारेज गर्नुहोस्"
"सूचना खारेज गरियो"
+ "व्यक्तिगत"
+ "कार्यसम्बन्धी"
+ "कार्य प्रोफाइल"
+ "कार्यसम्बन्धी अनुप्रयोगहरू यहाँ प्राप्त गर्नुहोस्"
+ "कार्यसम्बन्धी प्रत्येक अनुप्रयोगमा एउटा ब्याज छ र तपाईंको संगठनले यसलाई सुरक्षित राखेको छ । अझ सजिलो गरी पहुँच राख्नका लागि अनुप्रयोगहरूलाई आफ्नो गृहस्क्रिनमा सार्नुहोस्।"
+ "तपाईंको सङ्गठनले व्यवस्थापन गरेको"
+ "सूचना र अनुप्रयोगहरू निष्क्रिय छन्"
+ "बन्द गर्नुहोस्"
+ "बन्द गरियो"
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 7e8def4ca8..64f4d7912b 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -40,18 +40,23 @@
"Er zijn geen apps gevonden die overeenkomen met \'%1$s\'"
"Zoeken naar meer apps"
"Meldingen"
+ "Tik en houd vast om snelkoppeling toe te voegen."
+ "Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken."
"Er is geen ruimte meer op dit startscherm."
"Geen ruimte meer in het vak \'Favorieten\'"
"Lijst met apps"
+ "Lijst met persoonlijke apps"
+ "Lijst met werk-apps"
"Homepage"
"Verwijderen"
"Deïnstalleren"
"App-info"
+ "Installeren"
"Snelle links instellen"
"Een app toestaan snelkoppelingen toe te voegen zonder tussenkomst van de gebruiker."
- "instellingen en snelkoppelingen op de homepage lezen"
+ "instellingen en snelkoppelingen op startscherm lezen"
"De app toestaan de instellingen en snelkoppelingen op de homepage te lezen."
- "instellingen en snelkoppelingen op de homepage schrijven"
+ "instellingen en snelkoppelingen op startscherm zetten"
"De app toestaan de instellingen en snelkoppelingen op de homepage te wijzigen."
"%1$s mag niet bellen"
"Probleem bij het laden van widget"
@@ -59,6 +64,10 @@
"Dit is een systeemapp die niet kan worden verwijderd."
"Naamloze map"
"%1$s is uitgeschakeld"
+
+ - %1$s heeft %2$d meldingen
+ - %1$s heeft %2$d melding
+
"Pagina %1$d van %2$d"
"Startscherm %1$d van %2$d"
"Nieuwe startschermpagina"
@@ -70,21 +79,21 @@
"Map: %1$s"
"Widgets"
"Achtergrond"
- "Instellingen voor homepage"
+ "Instellingen startscherm"
"Uitgeschakeld door je beheerder"
- "Overzicht"
"Draaien van startscherm toestaan"
"Wanneer de telefoon gedraaid is"
- "Huidige scherminstelling staat draaien niet toe"
"Meldingsstipjes"
"Aan"
"Uit"
"Toegang tot meldingen vereist"
"Als je meldingsstipjes wilt weergeven, schakel je app-meldingen in voor %1$s"
"Instellingen wijzigen"
+ "Meldingsstipjes weergeven"
"Pictogram toevoegen aan startscherm"
"Voor nieuwe apps"
"Vorm van pictogram wijzigen"
+ "op het startscherm"
"Systeemstandaard gebruiken"
"Vierkant"
"Squircle"
@@ -99,7 +108,9 @@
"%1$s wordt gedownload, %2$s voltooid"
"%1$s wacht op installatie"
"%1$s-widgets"
- "Toevoegen aan homepage"
+ "Lijst met widgets"
+ "Lijst met widgets gesloten"
+ "Toevoegen aan startscherm"
"Item hier naartoe verplaatsen"
"Item toegevoegd aan startscherm"
"Item verwijderd"
@@ -114,9 +125,6 @@
"Map maken met: %1$s"
"Map gemaakt"
"Verplaatsen naar startscherm"
- "Scherm naar links verplaatsen"
- "Scherm naar rechts verplaatsen"
- "Scherm verplaatst"
"Formaat aanpassen"
"Breedte vergroten"
"Hoogte vergroten"
@@ -124,8 +132,16 @@
"Hoogte verkleinen"
"Formaat van widget gewijzigd in breedte %1$s en hoogte %2$s"
"Snelkoppelingen"
- "%1$d snelkoppelingen voor %2$s"
- "%1$d snelkoppelingen en %2$d meldingen voor %3$s"
+ "Snelkoppelingen en meldingen"
"Sluiten"
"Melding gesloten"
+ "Privé"
+ "Werk"
+ "Werkprofiel"
+ "Zoek hier naar werk-apps"
+ "Elke werk-app heeft een badge en wordt beveiligd door je organisatie. Verplaats apps naar je startscherm voor snelle toegang."
+ "Beheerd door je organisatie"
+ "Meldingen en apps zijn uitgeschakeld"
+ "Sluiten"
+ "Gesloten"
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
new file mode 100644
index 0000000000..5fa6607bf9
--- /dev/null
+++ b/res/values-or/strings.xml
@@ -0,0 +1,149 @@
+
+
+
+
+ "ଲଞ୍ଚର୍3"
+
+ "କାମ"
+ "ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ"
+ "ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"
+ "ନିରାପଦ ମୋଡରେ ଡାଉନଲୋଡ୍ ହେଇଥିବା ଆପ୍ ଅକ୍ଷମ କରାଗଲା"
+ "ନିରାପଦ ମୋଡରେ ୱିଜେଟ୍ ଅକ୍ଷମ କରାଗଲା"
+ "ଶର୍ଟକଟ୍ ଉପଲବ୍ଧ ନାହିଁ"
+ "ହୋମ୍ ସ୍କ୍ରୀନ୍"
+ "କାର୍ଯ୍ୟ କଷ୍ଟମ୍ କରନ୍ତୁ"
+ "ୱିଜେଟ୍ ନେବାକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ।"
+ "ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ ଏବଂ ଏକ ୱିଜେଟ୍ ନେବାକୁ ଧରି ରଖନ୍ତୁ କିମ୍ୱା କଷ୍ଟମ୍ କାର୍ଯ୍ୟପ୍ରକ୍ରିୟା ବ୍ୟବହାର କରନ୍ତୁ।"
+ "%1$d × %2$d"
+ "%1$d ଓସାର ଓ %2$d ଉଚ୍ଚ"
+ "ମାନୁଆଲ୍ ଭାବରେ ରଖିବାକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ"
+ "ସ୍ୱଚାଳିତ ଭାବେ ଯୋଡ଼ନ୍ତୁ"
+ "ଆପ୍ ଖୋଜନ୍ତୁ"
+ "ଆପ୍ ଲୋଡ୍ ହେଉଛି..."
+ "\"%1$s\" ସହିତ ମେଳ ହେଉଥିବା କୌଣସି ଆପ୍ ମିଳିଲା ନାହିଁ"
+ "ଅଧିକ ଆପ୍ ଖୋଜନ୍ତୁ"
+ "ବିଜ୍ଞପ୍ତି"
+ "ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"
+ "ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ ଏବଂ ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ଧରି ରଖନ୍ତୁ କିମ୍ୱା କଷ୍ଟମ୍ ପ୍ରକ୍ରିୟା ବ୍ୟବହାର କରନ୍ତୁ।"
+ "ହୋମ୍ ସ୍କ୍ରୀନ ପାଇଁ ଆଉ କୋଠରୀ ନାହିଁ"
+ "ମନପସନ୍ଦ ଟ୍ରେରେ ଆଉ କୋଠରୀ ନାହିଁ"
+ "ଆପ୍ ତାଲିକା"
+ "ବ୍ୟକ୍ତିଗତ ଆପ୍ ତାଲିକା"
+ "କାର୍ଯ୍ୟକାରୀ ଆପ୍ ତାଲିକା"
+ "ହୋମ୍"
+ "ବାହାର କରନ୍ତୁ"
+ "ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"
+ "ଆପ୍ ସୂଚନା"
+ "ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"
+ "ଶର୍ଟକଟ୍ ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"
+ "ୟୁଜରଙ୍କ ବିନା ହସ୍ତକ୍ଷେପରେ ଶର୍ଟକଟ୍ ଯୋଡ଼ିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"
+ "ହୋମ୍ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍ ପଢ଼ନ୍ତୁ"
+ "ହୋମରେ ସେଟିଙ୍ଗ ପଢ଼ିବାକୁ ଆପ ଏବଂ ଶର୍ଟକଟକୁ ଅନୁମତି ଦିଏ।"
+ "ହୋମ୍ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍ ଲେଖନ୍ତୁ"
+ "ହୋମରେ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"
+ "ଫୋନ୍ କଲ୍ କରିବାକୁ %1$sକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"
+ "ୱିଜେଟ୍ ଲୋଡ୍ ହେବାରେ ସମସ୍ୟା ଅଛି"
+ "ସେଟ୍ ଅପ୍ କରନ୍ତୁ"
+ "ଏହା ଏକ ସିଷ୍ଟମ୍ ଆପ୍ ଅଟେ ଏବଂ ଏହା ଅନଇନଷ୍ଟଲ୍ କରାଯାଇ ପାରିବ ନାହିଁ।"
+ "ବେନାମୀ ଫୋଲ୍ଡର୍"
+ "%1$s ଅକ୍ଷମ କରାଗଲା"
+
+ - %1$s, ରେ %2$d ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଅଛି
+ - %1$s, ରେ %2$d ବିଜ୍ଞପ୍ତି ଅଛି
+
+ "ମୋଟ %2$dରୁ %1$d ନମ୍ବର ପୃଷ୍ଠା"
+ "%2$dରୁ %1$d ହୋମ୍ ସ୍କ୍ରୀନ୍"
+ "ନୂଆ ହୋମ୍ ସ୍କ୍ରୀନ୍ ପୃଷ୍ଠା"
+ "%2$d / %1$dର ଫୋଲ୍ଡର ଖୋଲାଗଲା"
+ "ଫୋଲ୍ଡର୍ ବନ୍ଦ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"
+ "ନାମ ବଦଳାଇବା ସେଭ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"
+ "ଫୋଲ୍ଡର ବନ୍ଦ କରାଗଲା"
+ "ଫୋଲ୍ଡରର ନାମ %1$sକୁ ବଦଳାଗଲା"
+ "ଫୋଲ୍ଡର: %1$s"
+ "ୱିଜେଟ୍"
+ "ୱାଲପେପର୍"
+ "ହୋମ୍ ସେଟିଙ୍ଗ"
+ "ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି"
+ "ହୋମ୍ ସ୍କ୍ରୀନ୍ ବୁଲାଇବା ଅନୁମତି ଦିଅନ୍ତୁ"
+ "ଯେତେବେଳେ ଫୋନକୁ ବୁଲାଯାଇଥାଏ"
+ "ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁଗୁଡ଼ିକ"
+ "ଅନ୍"
+ "ଅଫ୍"
+ "ବିଜ୍ଞପ୍ତି ଆକ୍ସେସ୍ ଆବଶ୍ୟକ ଅଟେ"
+ "ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁ ଦେଖାଇବାକୁ, %1$s ପାଇଁ ଆପ୍ ବିଜ୍ଞପ୍ତି ଅନ୍ କରନ୍ତୁ"
+ "ସେଟିଙ୍ଗ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"
+ "ବିଜ୍ଞପ୍ତି ଡଟ୍ଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"
+ "ହୋମ୍ ସ୍କ୍ରୀନରେ ଆଇକନ୍କୁ ଯୋଡ଼ନ୍ତୁ"
+ "ନୂଆ ଆପ୍ ପାଇଁ"
+ "ଆଇକନ୍ର ଆକାର ପରିବର୍ତ୍ତନ କରନ୍ତୁ"
+ "ହୋମ୍ ସ୍କ୍ରୀନ୍ ଉପରେ"
+ "ସିଷ୍ଟମ ଡିଫଲ୍ଟ ବ୍ୟବହାର କରନ୍ତୁ"
+ "ବର୍ଗାକାର"
+ "ବର୍ଗାକାରର ବୃତ୍ତ"
+ "ବୃତ୍ତ"
+ "ଟିଅରଡ୍ରପ୍"
+ "ଆଇକନ୍ ଆକାର ପରିବର୍ତ୍ତନ ଲାଗୁ କରୁଛି"
+ "ଅଜଣା"
+ "ବାହାର କରନ୍ତୁ"
+ "ସର୍ଚ୍ଚ କରନ୍ତୁ"
+ "ଏହି ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ"
+ "ଏହି ଆଇକନ୍ ପାଇଁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ। ଏହାକୁ ଆପଣ ଆପ୍ ପାଇଁ ବାହାର କରିପାରିବେ କିମ୍ୱା ସର୍ଚ୍ଚ କରି ପାରିବେ ଏବଂ ଏହାକୁ ମାନୁଆଲ୍ ଭାବରେ ଇନଷ୍ଟଲ୍ କରିପାରିବେ।"
+ "%1$s ଡାଉନଲୋଡ୍ ହେଉଛି, %2$s ସମ୍ପୂର୍ଣ୍ଣ"
+ "%1$s ଇନଷ୍ଟଲ୍ ହେବାକୁ ଅପେକ୍ଷା କରିଛି"
+ "%1$s ୱିଜେଟ୍"
+
+
+
+
+ "ହୋମ୍ ସ୍କ୍ରୀନରେ ଯୋଡ଼ନ୍ତୁ"
+ "ଆଇଟମ୍କୁ ଏଠାକୁ ଘୁଞ୍ଚାନ୍ତୁ"
+ "ହୋମ୍ ସ୍କ୍ରୀନରେ ଆଇଟମ୍ ଯୋଡ଼ାଗଲା"
+ "ଆଇଟମ୍ ବାହାର କରାଗଲା"
+ "ଆଇଟମ୍ ଘୁଞ୍ଚାନ୍ତୁ"
+ "ଧାଡ଼ି %1$s ସ୍ତମ୍ଭ %2$sକୁ ନିଅନ୍ତୁ"
+ "%1$s ସ୍ଥିତିକୁ ନିଅନ୍ତୁ"
+ "ପସନ୍ଦର ସ୍ଥିତି %1$sକୁ ନିଅନ୍ତୁ"
+ "ଆଇଟମ୍ ଘୁଞ୍ଚେଇ ଦିଆଗଲା"
+ "ଏହି ଫୋଲ୍ଡରରେ ଯୋଡ଼ନ୍ତୁ: %1$s"
+ "%1$s ସହିତ ଫୋଲ୍ଡରରେ ଯୋଡ଼ନ୍ତୁ"
+ "ଫୋଲ୍ଡରରେ ଆଇଟମ୍ ଯୋଡ଼ାଗଲା"
+ "ଏହି ନାମରେ ଫୋଲ୍ଡର ତିଆରି କରନ୍ତୁ: %1$s"
+ "ଫୋଲ୍ଡର ତିଆରି କରାଗଲା"
+ "ହାମ୍ ସ୍କ୍ରୀନକୁ ଘୁଞ୍ଚାନ୍ତୁ"
+ "ଆକାର ବଦଳାନ୍ତୁ"
+ "ଚଉଡ଼ା ବଢ଼ାନ୍ତୁ"
+ "ଉଚ୍ଚତା ବଢ଼ାନ୍ତୁ"
+ "ଚଉଡ଼ା କମ୍ କରନ୍ତୁ"
+ "ଉଚ୍ଚତା କମ୍ କରନ୍ତୁ"
+ "ୱିଜେଟକୁ %1$s ଓସାର ଓ %2$s ଉଚ୍ଚରେ ପୁନଃଆକାର ଦିଆଗଲା"
+ "ଶର୍ଟକଟ୍"
+ "ଶର୍ଟକଟ୍ ଓ ବିଜ୍ଞପ୍ତି"
+ "ଖାରଜ କରନ୍ତୁ"
+ "ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା"
+ "ବ୍ୟକ୍ତିଗତ"
+ "କାମ"
+ "ୱର୍କ ପ୍ରୋଫାଇଲ୍"
+ "ଏଠାରେ କାମ ଆପ୍ ଖୋଜନ୍ତୁ"
+ "ପ୍ରତ୍ୟେକ କାଯ୍ୟକାରୀ ଆପ୍ର ଗୋଟିଏ ବ୍ୟାଜ୍ (ଚିହ୍ନ) ଅଛି, ଯାହାକୁ ଆପଣଙ୍କ ସଂସ୍ଥା ସୁରକ୍ଷିତ ରଖିଥାଏ। ସହଜରେ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଆପ୍କୁ ହୋମ୍ ସ୍କ୍ରୀନ୍ ଉପରକୁ ଆଣନ୍ତୁ।"
+ "ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ"
+ "ବିଜ୍ଞପ୍ତି ଓ ଆପ୍ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"
+ "ବନ୍ଦ କରନ୍ତୁ"
+ "ବନ୍ଦ ହୋଇଯାଇଛି"
+
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000000..c0778690ad
--- /dev/null
+++ b/res/values-pa-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "ਦਫ਼ਤਰ"
+ "ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"
+ "ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"
+ "ਡਾਊਨਲੋਡ ਕੀਤਾ ਐਪ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"
+ "ਵਿਜੇਟ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"
+ "ਸ਼ਾਰਟਕੱਟ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ"
+ "ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ"
+ "ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਛੋਹਵੋT & ਹੋਲਡ ਕਰੋ।"
+ "ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"
+ "%1$d × %2$d"
+ "%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"
+ "ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"
+ "ਸਵੈਚਲਿਤ ਤਰੀਕੇ ਨਾਲ ਸ਼ਾਮਲ ਕਰੋ"
+ "ਐਪਾਂ ਖੋਜੋ"
+ "ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."
+ "\"%1$s\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"
+ "ਹੋਰ ਐਪਾਂ ਖੋਜੋ"
+ "ਸੂਚਨਾਵਾਂ"
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਡਬਲ ਟੈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ ਜਾਂ ਵਿਉਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"
+ "ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ ਲਈ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ ਹੈ।"
+ "ਮਨਪਸੰਦ ਟ੍ਰੇ ਵਿੱਚ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ।"
+ "ਐਪ ਸੂਚੀ"
+ "ਨਿੱਜੀ ਐਪਾਂ ਦੀ ਸੂਚੀ"
+ "ਕਾਰਜ-ਸਥਾਨ ਸੰਬੰਧੀ ਐਪਾਂ ਦੀ ਸੂਚੀ"
+ "ਹੋਮ"
+ "ਹਟਾਓ"
+ "ਅਣਸਥਾਪਤ ਕਰੋ"
+ "ਐਪ ਜਾਣਕਾਰੀ"
+ "ਸਥਾਪਤ ਕਰੋ"
+ "ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"
+ "ਇੱਕ ਐਪ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
+ "ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹੋ"
+ "ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
+ "ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਲਿਖੋ"
+ "ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
+ "%1$s ਨੂੰ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"
+ "ਵਿਜੇਟ ਲੋਡ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ"
+ "ਸਥਾਪਤ ਕਰੋ"
+ "ਇਹ ਇੱਕ ਸਿਸਟਮ ਐਪ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"
+ "ਬਿਨਾਂ ਨਾਮ ਦਿੱਤਾ ਫੋਲਡਰ"
+ "%1$s ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"
+
+ - %1$s, ਦੀ %2$d ਸੂਚਨਾ
+ - %1$s, ਦੀਆਂ %2$d ਸੂਚਨਾਵਾਂ
+
+ "ਸਫ਼ਾ %2$d ਦਾ %1$d"
+ "ਹੋਮ ਸਕ੍ਰੀਨ %2$d ਦੀ %1$d"
+ "ਨਵਾਂ ਹੋਮ ਸਕ੍ਰੀਨ ਸਫ਼ਾ"
+ "ਫੋਲਡਰ ਖੋਲ੍ਹਿਆ, %1$d ਬਾਇ %2$d"
+ "ਫੋਲਡਰ ਬੰਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"
+ "ਬਦਲੇ ਗਏ ਨਾਮ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"
+ "ਫੋਲਡਰ ਬੰਦ ਕੀਤਾ"
+ "ਫੋਲਡਰ ਨੂੰ %1$s ਮੁੜ ਨਾਮ ਦਿੱਤਾ ਗਿਆ"
+ "ਫੋਲਡਰ: %1$s"
+ "ਵਿਜੇਟ"
+ "ਵਾਲਪੇਪਰ"
+ "ਹੋਮ ਸੈਟਿੰਗਾਂ"
+ "ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"
+ "ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"
+ "ਸੂਚਨਾ ਬਿੰਦੂ"
+ "ਚਾਲੂ"
+ "ਬੰਦ"
+ "ਸੂਚਨਾ ਪਹੁੰਚ ਲੋੜੀਂਦੀ ਹੈ"
+ "ਸੂਚਨਾ ਬਿੰਦੂਆਂ ਦਿਖਾਉਣ ਲਈ, %1$s ਲਈ ਐਪ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਕਰੋ"
+ "ਸੈਟਿੰਗਾਂ ਬਦਲੋ"
+ "ਸੂਚਨਾ ਬਿੰਦੂ ਦਿਖਾਓ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"
+ "ਨਵੀਆਂ ਐਪਾਂ ਲਈ"
+ "ਪ੍ਰਤੀਕ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ"
+ "ਸਿਸਟਮ ਦੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈਟਿੰਗ ਵਰਤੋ"
+ "ਵਰਗ"
+ "ਵਰਗਾਕਾਰ-ਚੱਕਰ"
+ "ਚੱਕਰ"
+ "ਹੰਝੂ ਦੀ ਬੂੰਦ"
+ "ਪ੍ਰਤੀਕ ਦੀ ਆਕ੍ਰਿਤੀ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"
+ "ਅਗਿਆਤ"
+ "ਹਟਾਓ"
+ "ਖੋਜੋ"
+ "ਇਹ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"
+ "ਇਸ ਪ੍ਰਤੀਕ ਲਈ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਖੋਜ ਸਕਦੇ ਹੋ ਅਤੇ ਇਸਨੂੰ ਮੈਨੂਅਲੀ ਸਥਾਪਤ ਕਰ ਸਕਦੇ ਹੋ।"
+ "%1$s ਡਾਉਨਲੋਡ ਹੋਰ ਰਿਹਾ ਹੈ, %2$s ਸੰਪੂਰਣ"
+ "%1$s ਸਥਾਪਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"
+ "%1$s ਵਿਜੇਟ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"
+ "ਆਈਟਮ ਨੂੰ ਇੱਥੇ ਮੂਵ ਕਰੋ"
+ "ਆਈਟਮ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"
+ "ਅਈਟਮ ਹਟਾਈ ਗਈ"
+ "ਆਈਟਮ ਨੂੰ ਮੂਵ ਕਰੋ"
+ "ਕਤਾਰ %1$s ਕਾਲਮ %2$s ਵਿੱਚ ਮੂਵ ਕਰੋ"
+ "ਸਥਿਤੀ %1$s ਵਿੱਚ ਮੂਵ ਕਰੋ"
+ "ਮਨਪਸੰਦ ਸਥਿਤੀ %1$s ਵਿੱਚ ਮੂਵ ਕਰੋ"
+ "ਆਈਟਮ ਮੂਵ ਕੀਤੀ ਗਈ"
+ "ਇਸ ਫੋਲਡਰ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ: %1$s"
+ "%1$s ਦੇ ਨਾਲ ਫੋਲਡਰ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"
+ "ਆਈਟਮ ਨੂੰ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"
+ "ਇਸਦੇ ਨਾਲ ਫੋਲਡਰ ਬਣਾਓ: %1$s"
+ "ਫੋਲਡਰ ਬਣਾਇਆ ਗਿਆ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਮੂਵ ਕਰੋ"
+ "ਮੁੜ ਆਕਾਰ ਦਿਓ"
+ "ਚੌੜਾਈ ਵਧਾਓ"
+ "ਉਂਚਾਈ ਵਧਾਓ"
+ "ਚੌੜਾਈ ਘਟਾਓ"
+ "ਉਂਚਾਈ ਘਟਾਓ"
+ "ਵਿਜੈਟ ਨੂੰ ਚੌੜਾਈ %1$s ਉਂਚਾਈ %2$s ਨੂੰ ਮੁੜ ਆਕਾਰ ਦਿੱਤਾ"
+ "ਸ਼ਾਰਟਕੱਟ"
+ "%2$s ਲਈ %1$d ਸ਼ਾਰਟਕੱਟ"
+ "%3$s ਲਈ %1$d ਸ਼ਾਰਟਕੱਟ ਅਤੇ %2$d ਸੂਚਨਾਵਾਂ"
+ "ਖਾਰਜ ਕਰੋ"
+ "ਸੂਚਨਾ ਖਾਰਜ ਕੀਤੀ ਗਈ"
+ "ਨਿੱਜੀ"
+ "ਕਾਰਜ-ਸਥਾਨ"
+ "ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"
+ "ਕਾਰਜ-ਸਥਾਨ ਐਪਾਂ ਇੱਥੇ ਲੱਭੋ"
+ "ਹਰੇਕ ਕਾਰਜ-ਸਥਾਨ ਐਪ ਦਾ ਇੱਕ ਬੈਜ ਹੁੰਦਾ ਹੈ ਅਤੇ ਉਸਨੂੰ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸੁਰੱਖਿਅਤ ਰੱਖਿਆ ਜਾਂਦਾ ਹੈ। ਵਧੇਰੇ ਆਸਾਨ ਪਹੁੰਚ ਲਈ ਐਪਾਂ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਜਾਓ।"
+ "ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"
+ "ਸੂਚਨਾਵਾਂ ਅਤੇ ਐਪਾਂ ਬੰਦ ਹਨ"
+ "ਬੰਦ ਕਰੋ"
+ "ਬੰਦ ਕੀਤਾ ਗਿਆ"
+
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index cf5351c7a7..3400e7bdcf 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -27,10 +27,10 @@
"ਡਾਊਨਲੋਡ ਕੀਤਾ ਐਪ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"
"ਵਿਜੇਟ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"
"ਸ਼ਾਰਟਕੱਟ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"
- "ਮੁੱਖ ਸਕ੍ਰੀਨ"
- "ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਾਰਵਾਈਆਂ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ"
+ "ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ"
"ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਛੋਹਵੋT & ਹੋਲਡ ਕਰੋ।"
- "ਡਬਲ-ਟੈਪ & ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਹੋਲਡ ਕਰੋ ਅਤੇ ਕਸਟਮ ਕਿਰਿਆਵਾਂ ਵਰਤੋ।"
+ "ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"
"%1$d × %2$d"
"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"
"ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"
@@ -40,25 +40,34 @@
"\"%1$s\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"
"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"
"ਸੂਚਨਾਵਾਂ"
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"
+ "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਡਬਲ ਟੈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ ਜਾਂ ਵਿਉਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"
"ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ ਲਈ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ ਹੈ।"
"ਮਨਪਸੰਦ ਟ੍ਰੇ ਵਿੱਚ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ।"
"ਐਪ ਸੂਚੀ"
+ "ਨਿੱਜੀ ਐਪਾਂ ਦੀ ਸੂਚੀ"
+ "ਕਾਰਜ-ਸਥਾਨ ਸੰਬੰਧੀ ਐਪਾਂ ਦੀ ਸੂਚੀ"
"ਹੋਮ"
"ਹਟਾਓ"
- "ਸਥਾਪਨਾ ਰੱਦ ਕਰੋ"
+ "ਅਣਸਥਾਪਤ ਕਰੋ"
"ਐਪ ਜਾਣਕਾਰੀ"
- "ਸ਼ਾਰਟਕੱਟ ਇੰਸਟੌਲ ਕਰੋ"
- "ਇੱਕ ਐਪ ਨੂੰ ਉਪਭੋਗਤਾ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
+ "ਸਥਾਪਤ ਕਰੋ"
+ "ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"
+ "ਇੱਕ ਐਪ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹੋ"
"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਲਿਖੋ"
"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"
- "%1$s ਨੂੰ ਫੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"
+ "%1$s ਨੂੰ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"
"ਵਿਜੇਟ ਲੋਡ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ"
"ਸਥਾਪਤ ਕਰੋ"
"ਇਹ ਇੱਕ ਸਿਸਟਮ ਐਪ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"
"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤਾ ਫੋਲਡਰ"
"%1$s ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"
+
+ - %1$s, ਦੀ %2$d ਸੂਚਨਾ
+ - %1$s, ਦੀਆਂ %2$d ਸੂਚਨਾਵਾਂ
+
"ਸਫ਼ਾ %2$d ਦਾ %1$d"
"ਹੋਮ ਸਕ੍ਰੀਨ %2$d ਦੀ %1$d"
"ਨਵਾਂ ਹੋਮ ਸਕ੍ਰੀਨ ਸਫ਼ਾ"
@@ -72,51 +81,52 @@
"ਵਾਲਪੇਪਰ"
"ਹੋਮ ਸੈਟਿੰਗਾਂ"
"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"
- "ਰੂਪ-ਰੇਖਾ"
- "ਮੁੱਖ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"
"ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"
- "ਵਰਤਮਾਨ ਡਿਸਪਲੇ ਸੈਟਿੰਗ ਘੁੰਮਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦੀ ਹੈ"
"ਸੂਚਨਾ ਬਿੰਦੂ"
"ਚਾਲੂ"
"ਬੰਦ"
"ਸੂਚਨਾ ਪਹੁੰਚ ਲੋੜੀਂਦੀ ਹੈ"
- "ਸੂਚਨਾ ਬਿੰਦੀਆਂ ਦਿਖਾਉਣ ਲਈ, %1$s ਲਈ ਐਪ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਕਰੋ"
+ "ਸੂਚਨਾ ਬਿੰਦੂਆਂ ਦਿਖਾਉਣ ਲਈ, %1$s ਲਈ ਐਪ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਕਰੋ"
"ਸੈਟਿੰਗਾਂ ਬਦਲੋ"
- "ਮੁੱਖ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"
+ "ਸੂਚਨਾ ਬਿੰਦੂ ਦਿਖਾਓ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"
"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"
- "ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"
+ "ਪ੍ਰਤੀਕ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ"
"ਸਿਸਟਮ ਦੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈਟਿੰਗ ਵਰਤੋ"
"ਵਰਗ"
"ਵਰਗਾਕਾਰ-ਚੱਕਰ"
"ਚੱਕਰ"
"ਹੰਝੂ ਦੀ ਬੂੰਦ"
- "ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"
+ "ਪ੍ਰਤੀਕ ਦੀ ਆਕ੍ਰਿਤੀ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"
"ਅਗਿਆਤ"
"ਹਟਾਓ"
"ਖੋਜੋ"
"ਇਹ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"
- "ਇਸ ਆਈਕਨ ਲਈ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਖੋਜ ਸਕਦੇ ਹੋ ਅਤੇ ਇਸਨੂੰ ਮੈਨੂਅਲੀ ਇੰਸਟੌਲ ਕਰ ਸਕਦੇ ਹੋ।"
+ "ਇਸ ਪ੍ਰਤੀਕ ਲਈ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਖੋਜ ਸਕਦੇ ਹੋ ਅਤੇ ਇਸਨੂੰ ਮੈਨੂਅਲੀ ਸਥਾਪਤ ਕਰ ਸਕਦੇ ਹੋ।"
"%1$s ਡਾਉਨਲੋਡ ਹੋਰ ਰਿਹਾ ਹੈ, %2$s ਸੰਪੂਰਣ"
- "%1$s ਸਥਾਪਿਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"
+ "%1$s ਸਥਾਪਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"
"%1$s ਵਿਜੇਟ"
- "ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜੋ"
+
+
+
+
+ "ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"
"ਆਈਟਮ ਨੂੰ ਇੱਥੇ ਮੂਵ ਕਰੋ"
- "ਆਈਟਮ ਨੂੰ ਮੁੱਖ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"
+ "ਆਈਟਮ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"
"ਅਈਟਮ ਹਟਾਈ ਗਈ"
"ਆਈਟਮ ਨੂੰ ਮੂਵ ਕਰੋ"
"ਕਤਾਰ %1$s ਕਾਲਮ %2$s ਵਿੱਚ ਮੂਵ ਕਰੋ"
"ਸਥਿਤੀ %1$s ਵਿੱਚ ਮੂਵ ਕਰੋ"
"ਮਨਪਸੰਦ ਸਥਿਤੀ %1$s ਵਿੱਚ ਮੂਵ ਕਰੋ"
"ਆਈਟਮ ਮੂਵ ਕੀਤੀ ਗਈ"
- "ਇਸ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜੋ: %1$s"
- "%1$s ਦੇ ਨਾਲ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜੋ"
+ "ਇਸ ਫੋਲਡਰ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ: %1$s"
+ "%1$s ਦੇ ਨਾਲ ਫੋਲਡਰ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"
"ਆਈਟਮ ਨੂੰ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"
"ਇਸਦੇ ਨਾਲ ਫੋਲਡਰ ਬਣਾਓ: %1$s"
"ਫੋਲਡਰ ਬਣਾਇਆ ਗਿਆ"
- "ਮੁੱਖ ਸਕ੍ਰੀਨ ਵਿੱਚ ਮੂਵ ਕਰੋ"
- "ਸਕ੍ਰੀਨ ਨੂੰ ਖੱਬੇ ਮੂਵ ਕਰੋ"
- "ਸਕ੍ਰੀਨ ਨੂੰ ਸੱਜੇ ਮੂਵ ਕਰੋ"
- "ਸਕ੍ਰੀਨ ਨੂੰ ਮੂਵ ਕੀਤਾ ਗਿਆ"
+ "ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਮੂਵ ਕਰੋ"
"ਮੁੜ ਆਕਾਰ ਦਿਓ"
"ਚੌੜਾਈ ਵਧਾਓ"
"ਉਂਚਾਈ ਵਧਾਓ"
@@ -124,8 +134,16 @@
"ਉਂਚਾਈ ਘਟਾਓ"
"ਵਿਜੈਟ ਨੂੰ ਚੌੜਾਈ %1$s ਉਂਚਾਈ %2$s ਨੂੰ ਮੁੜ ਆਕਾਰ ਦਿੱਤਾ"
"ਸ਼ਾਰਟਕੱਟ"
- "%2$s ਲਈ %1$d ਸ਼ਾਰਟਕੱਟ"
- "%3$s ਲਈ %1$d ਸ਼ਾਰਟਕੱਟ ਅਤੇ %2$d ਸੂਚਨਾਵਾਂ"
+ "ਸ਼ਾਰਟਕੱਟ ਅਤੇ ਸੂਚਨਾਵਾਂ"
"ਖਾਰਜ ਕਰੋ"
"ਸੂਚਨਾ ਖਾਰਜ ਕੀਤੀ ਗਈ"
+ "ਨਿੱਜੀ"
+ "ਕਾਰਜ-ਸਥਾਨ"
+ "ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"
+ "ਕਾਰਜ-ਸਥਾਨ ਐਪਾਂ ਇੱਥੇ ਲੱਭੋ"
+ "ਹਰੇਕ ਕਾਰਜ-ਸਥਾਨ ਐਪ ਦਾ ਇੱਕ ਬੈਜ ਹੁੰਦਾ ਹੈ ਅਤੇ ਉਸਨੂੰ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸੁਰੱਖਿਅਤ ਰੱਖਿਆ ਜਾਂਦਾ ਹੈ। ਵਧੇਰੇ ਆਸਾਨ ਪਹੁੰਚ ਲਈ ਐਪਾਂ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਜਾਓ।"
+ "ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"
+ "ਸੂਚਨਾਵਾਂ ਅਤੇ ਐਪਾਂ ਬੰਦ ਹਨ"
+ "ਬੰਦ ਕਰੋ"
+ "ਬੰਦ ਕੀਤਾ ਗਿਆ"
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index c07f7defb3..776f39dce4 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -40,13 +40,18 @@
"Nie znaleziono aplikacji pasujących do zapytania „%1$s”"
"Wyszukaj więcej aplikacji"
"Powiadomienia"
+ "Kliknij i przytrzymaj, by wybrać skrót."
+ "Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych."
"Brak miejsca na tym ekranie głównym."
"Brak miejsca w Ulubionych"
"Lista aplikacji"
+ "Lista aplikacji osobistych"
+ "Lista aplikacji do pracy"
"Ekran główny"
"Usuń"
"Odinstaluj"
"O aplikacji"
+ "Zainstaluj"
"instalowanie skrótów"
"Pozwala aplikacji dodawać skróty bez interwencji użytkownika."
"odczytywanie ustawień i skrótów na ekranie głównym"
@@ -59,6 +64,12 @@
"To aplikacja systemowa i nie można jej odinstalować."
"Folder bez nazwy"
"Aplikacja %1$s jest wyłączona"
+
+ - %1$s – %2$d powiadomienia
+ - %1$s – %2$d powiadomień
+ - %1$s – %2$d powiadomienia
+ - %1$s – %2$d powiadomienie
+
"Strona %1$d z %2$d"
"Ekran główny %1$d z %2$d"
"Nowa strona ekranu głównego"
@@ -72,19 +83,19 @@
"Tapety"
"Ustawienia strony głównej"
"Funkcja wyłączona przez administratora"
- "Przegląd"
"Zezwalaj na obrót ekranu głównego"
"Po obróceniu telefonu"
- "Obecne ustawienia wyświetlania nie pozwalają na obrót ekranu"
"Plakietki z powiadomieniami"
"Włączono"
"Wyłączono"
"Wymagany jest dostęp do powiadomień"
"Aby pokazać plakietki z powiadomieniami, włącz powiadomienia aplikacji %1$s"
"Zmień ustawienia"
+ "Pokaż plakietki z powiadomieniami"
"Dodaj ikonę do ekranu głównego"
"W przypadku nowych aplikacji"
"Zmień kształt ikon"
+ "na ekranie głównym"
"Użyj ustawienia domyślnego"
"Kwadrat"
"Zaokrąglony kwadrat"
@@ -99,6 +110,8 @@
"Pobieranie elementu %1$s, ukończono: %2$s"
"%1$s oczekuje na instalację"
"%1$s – widżety"
+ "Lista widgetów"
+ "Lista widgetów zamknięta"
"Dodaj do strony głównej"
"Przenieś element tutaj"
"Element został dodany do ekranu głównego"
@@ -114,9 +127,6 @@
"Utwórz folder z: %1$s"
"Folder został utworzony"
"Przenieś na ekran główny"
- "Przenieś ekran w lewo"
- "Przenieś ekran w prawo"
- "Ekran został przeniesiony"
"Zmień rozmiar"
"Zwiększ szerokość"
"Zwiększ wysokość"
@@ -124,8 +134,16 @@
"Zmniejsz wysokość"
"Szerokość i wysokość widżetu zmieniła się na %1$s x %2$s"
"Skróty"
- "Skróty aplikacji %2$s: %1$d"
- "Skróty (%1$d) i powiadomienia (%2$d) aplikacji %3$s"
+ "Skróty i powiadomienia"
"Odrzuć"
"Powiadomienie odrzucone"
+ "Osobiste"
+ "Praca"
+ "Profil służbowy"
+ "Aplikacje do pracy"
+ "Każda aplikacja do pracy ma plakietkę, a o jej bezpieczeństwo dba Twoja organizacja. Aplikacje można przenieść na ekran główny, by były łatwiej dostępne."
+ "Profil zarządzany przez Twoją organizację"
+ "Powiadomienia i aplikacje są wyłączone"
+ "Zamknij"
+ "Zamknięto"
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 100f07b66b..40105915ce 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -40,13 +40,18 @@
"Nenhuma aplicação correspondente a \"%1$s\""
"Pesquisar mais aplicações"
"Notificações"
+ "Toque sem soltar para escolher um atalho."
+ "Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas."
"Sem espaço suficiente neste Ecrã principal."
"Não existe mais espaço no tabuleiro de Favoritos"
"Lista de aplicações"
+ "Lista de aplicações pessoais"
+ "Lista de aplicações de trabalho"
"Ecrã principal"
"Remover"
"Desinstalar"
- "Inf. da aplicação"
+ "Info. da aplicação"
+ "Instalar"
"instalar atalhos"
"Permite a uma aplicação adicionar atalhos sem a intervenção do utilizador."
"ler definições e atalhos do Ecrã Principal"
@@ -59,6 +64,10 @@
"É uma aplicação de sistema e não pode ser desinstalada."
"Pasta sem nome"
"%1$s desativado"
+
+ - %1$s, tem %2$d notificações.
+ - %1$s, tem %2$d notificação.
+
"Página %1$d de %2$d"
"Ecrã principal %1$d de %2$d"
"Nova página do ecrã principal"
@@ -71,20 +80,20 @@
"Widgets"
"Imagens de fundo"
"Definições da página inicial"
- "Desativada pelo administrador"
- "Vista geral"
+ "Desativada pelo gestor"
"Permitir rotação do ecrã principal"
"Quando o telemóvel é rodado"
- "A definição de visualização atual não permite a rotação"
"Pontos de notificação"
"Ativada"
"Desativada"
"Acesso a notificações necessário"
"Para mostrar os Pontos de notificação, ative as notificações de aplicações para o %1$s"
"Alterar definições"
+ "Mostrar pontos de notificação"
"Adicionar ícone ao ecrã principal"
"Para novas aplicações"
"Alterar forma do ícone"
+ "no ecrã principal"
"Utilizar a predefinição do sistema"
"Quadrado"
"Quadrado e círculo"
@@ -99,6 +108,8 @@
"A transferir o %1$s, %2$s concluído"
"A aguardar a instalação do %1$s"
"Widgets de %1$s"
+ "Lista de widgets"
+ "Lista de widgets fechada."
"Adicionar ao Ecrã principal"
"Mover o item para aqui"
"Item adicionado ao ecrã principal"
@@ -114,9 +125,6 @@
"Criar pasta com: %1$s"
"Pasta criada"
"Mover para o Ecrã principal"
- "Mover ecrã para a esquerda"
- "Mover ecrã para a direita"
- "Ecrã movido"
"Redimensionar"
"Aumentar largura"
"Aumentar altura"
@@ -124,8 +132,16 @@
"Diminuir altura"
"Widget redimensionado para a largura %1$s, altura %2$s"
"Atalhos"
- "%1$d atalhos para a aplicação %2$s"
- "%1$d atalhos e %2$d notificações para a aplicação %3$s"
+ "Atalhos e notificações"
"Ignorar"
"Notificação ignorada"
+ "Pessoal"
+ "Trabalho"
+ "Perfil de trabalho"
+ "Encontrar as aplicações de trabalho aqui"
+ "Cada aplicação de trabalho apresenta um emblema, pelo que a sua entidade a mantém em segurança. Pode mover as aplicações para o ecrã principal para facilitar o acesso."
+ "Gerido pela sua entidade"
+ "As notificações e as aplicações estão desativadas."
+ "Fechar"
+ "Fechado"
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index d75159f94a..6238e7aefc 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -40,13 +40,18 @@
"Nenhum app encontrado que corresponda a \"%1$s\""
"Pesquisar mais apps"
"Notificações"
+ "Toque e segure para selecionar um atalho."
+ "Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas."
"Não há mais espaço na tela inicial."
"Sem espaço na bandeja de favoritos"
"Lista de apps"
+ "Lista de apps pessoais"
+ "Lista de apps profissionais"
"Início"
"Remover"
"Desinstalar"
"Informações do app"
+ "Instalar"
"instalar atalhos"
"Permite que um app adicione atalhos sem intervenção do usuário."
"ler configurações e atalhos da tela inicial"
@@ -59,6 +64,10 @@
"Este é um app do sistema e não pode ser desinstalado."
"Pasta sem nome"
"%1$s desativado"
+
+ - O app %1$s tem %2$d notificação
+ - O app %1$s tem %2$d notificações
+
"Página %1$d de %2$d"
"Tela inicial %1$d de %2$d"
"Nova página na tela inicial"
@@ -70,21 +79,21 @@
"Pasta: %1$s"
"Widgets"
"Planos de fundo"
- "Configurações da página inicial"
+ "Configurações da tela inicial"
"Desativado pelo administrador"
- "Visão geral"
"Permitir rotação da tela inicial"
"Quando o smartphone for girado"
- "A configuração atual de exibição não permite rotação"
"Pontos de notificação"
"Ativado"
"Desativado"
"Acesso a notificações necessário"
"Para mostrar pontos de notificação, ative as notificações de app para %1$s"
"Alterar configurações"
+ "Mostrar pontos de notificação"
"Adicionar ícone à tela inicial"
"Para novos apps"
"Alterar forma de ícones"
+ "na tela inicial"
"Usar padrão do sistema"
"Quadrado"
"Quadrado arredondado"
@@ -99,6 +108,8 @@
"Fazendo download de %1$s, %2$s concluído"
"Aguardando instalação de %1$s"
"Widgets do %1$s"
+ "Lista de widgets"
+ "Lista de widgets fechada"
"Adicionar à tela inicial"
"Mover item para cá"
"Item adicionado à tela inicial"
@@ -114,9 +125,6 @@
"Criar pasta com: %1$s"
"Pasta criada"
"Mover para a tela inicial"
- "Mover tela para a esquerda"
- "Mover tela para a direita"
- "Tela movida"
"Redimensionar"
"Aumentar largura"
"Aumentar altura"
@@ -124,8 +132,16 @@
"Diminuir altura"
"Widget redimensionado para a largura %1$s, altura %2$s"
"Atalhos"
- "%1$d atalhos para %2$s"
- "%1$d atalhos e %2$d notificações para o app %3$s"
+ "Atalhos e notificações"
"Dispensar"
"Notificação dispensada"
+ "Pessoais"
+ "Comerciais"
+ "Perfil de trabalho"
+ "Localizar apps de trabalho aqui"
+ "Cada app de trabalho tem um selo e é mantido em segurança pela sua organização. Mova os apps para sua tela inicial para facilitar o acesso."
+ "Gerenciados pela sua organização"
+ "As notificações e os apps estão desativados"
+ "Fechar"
+ "Fechado"
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 512d96d6b8..fb5fb96232 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -40,13 +40,18 @@
"Nu s-a găsit nicio aplicație pentru „%1$s\""
"Căutați mai multe aplicații"
"Notificări"
+ "Atingeți lung pentru a selecta o comandă rapidă."
+ "Atingeți lung pentru a selecta o comandă rapidă sau folosiți acțiuni personalizate."
"Nu mai este loc pe acest Ecran de pornire."
"Spațiu epuizat în bara Preferate"
"Lista de aplicații"
+ "Lista de aplicații personale"
+ "Lista de aplicații de serviciu"
"Ecran de pornire"
"Eliminați"
"Dezinstalați"
"Informații aplicație"
+ "Instalați"
"instalează comenzi rapide"
"Permite unei aplicații să adauge comenzi rapide fără intervenția utilizatorului."
"citește setări și comenzi rapide pentru ecranul de pornire"
@@ -59,6 +64,11 @@
"Aceasta este o aplicație de sistem și nu poate fi dezinstalată."
"Dosar fără nume"
"S-a dezactivat %1$s"
+
+ - %1$s are %2$d notificări
+ - %1$s are %2$d de notificări
+ - %1$s are %2$d notificare
+
"Pagina %1$d din %2$d"
"Ecranul de pornire %1$d din %2$d"
"Pagină nouă pe ecranul de pornire"
@@ -72,19 +82,19 @@
"Imagini de fundal"
"Setări pentru ecranul de pornire"
"Dezactivată de administrator"
- "Prezentare generală"
"Permiteți rotirea ecranului de pornire"
"Când telefonul este rotit"
- "Setarea actuală a afișajului nu permite rotirea"
"Puncte de notificare"
"Activat"
"Dezactivat"
"Este necesar accesul la notificări"
"Pentru a afișa punctele de notificare, activați notificările din aplicație pentru %1$s"
"Modificați setările"
+ "Afișați punctele de notificare"
"Adaugă pictograme în ecranul de pornire"
"Pentru aplicații noi"
"Schimbați forma pictogramei"
+ "pe ecranul de pornire"
"Folosiți setarea prestabilită a sistemului"
"Pătrat"
"Pătrat cu colțuri rotunjite"
@@ -99,6 +109,8 @@
"%1$s se descarcă (finalizat %2$s)"
"%1$s așteaptă instalarea"
"Widgeturi %1$s"
+ "Listă de widgeturi"
+ "Lista de widgeturi este închisă"
"Adăugați pe ecranul de pornire"
"Mutați elementul aici"
"Element adăugat pe ecranul de pornire"
@@ -114,9 +126,6 @@
"Creați dosar cu: %1$s"
"Dosar creat"
"Mutați pe ecranul de pornire"
- "Mutați ecranul la stânga"
- "Mutați ecranul la dreapta"
- "Ecran mutat"
"Redimensionați"
"Creșteți lățimea"
"Creșteți înălțimea"
@@ -124,8 +133,16 @@
"Reduceți înălțimea"
"Widgetul a fost redimensionat la lățimea %1$s și înălțimea %2$s"
"Comenzi rapide"
- "%1$d comenzi rapide pentru %2$s"
- "%1$d comenzi rapide și %2$d notificări pentru %3$s"
+ "Comenzi rapide și notificări"
"Închideți"
"Notificare închisă"
+ "Personale"
+ "Profesionale"
+ "Profil de serviciu"
+ "Găsiți aplicații de serviciu aici"
+ "Fiecare aplicație de serviciu are o insignă și este păstrată în siguranță de organizația dvs. Mutați aplicațiile pe ecranul de pornire pentru acces mai ușor."
+ "Gestionat de organizația dvs."
+ "Notificările și aplicațiile sunt dezactivate"
+ "Închideți"
+ "Închis"
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 923f3573b3..dd70521a8f 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -33,20 +33,25 @@
"Чтобы выбрать виджет или использовать специальные действия, нажмите на него дважды и не отпускайте."
"%1$d x %2$d"
"Ширина %1$d, высота %2$d"
- "Нажмите и удерживайте, чтобы добавить вручную"
+ "Нажмите и удерживайте, чтобы добавить вручную."
"Добавить автоматически"
"Поиск приложений"
"Загрузка приложений…"
"По запросу \"%1$s\" ничего не найдено"
"Искать другие приложения"
"Уведомления"
+ "Нажмите и удерживайте, чтобы выбрать ярлык."
+ "Нажмите дважды и удерживайте, чтобы выбрать ярлык или использовать специальные действия."
"На этом экране все занято"
"В разделе \"Избранное\" больше нет места"
"Список приложений"
+ "Открыть список личных приложений"
+ "Открыть список приложений для работы"
"Главный экран"
"Убрать"
"Удалить"
"О приложении"
+ "Установить"
"Создание ярлыков"
"Приложение сможет самостоятельно добавлять ярлыки."
"Доступ к настройкам и ярлыкам главного экрана"
@@ -59,8 +64,14 @@
"Это системное приложение, его нельзя удалить."
"Папка без названия"
"Приложение %1$s отключено"
+
+ - В приложении \"%1$s\" %2$d уведомление
+ - В приложении \"%1$s\" %2$d уведомления
+ - В приложении \"%1$s\" %2$d уведомлений
+ - В приложении \"%1$s\" %2$d уведомления
+
"Стр. %1$d из %2$d"
- "Главные экран %1$d из %2$d"
+ "Главный экран %1$d из %2$d"
"Новый экран"
"Папка открыта, %1$d x %2$d"
"Нажмите, чтобы закрыть папку"
@@ -72,19 +83,19 @@
"Обои"
"Настройки главного экрана"
"Функция отключена администратором"
- "Обзор"
"Разрешить поворачивать главный экран"
"Когда телефон повернут"
- "В настройках отключен поворот экрана"
"Значки уведомлений"
- "ВКЛ"
- "ВЫКЛ"
+ "Вкл."
+ "Выкл."
"Нет доступа к уведомлениям"
"Чтобы показывать значки уведомлений, включите уведомления в приложении \"%1$s\""
"Изменить настройки"
+ "Показывать значки уведомлений"
"Добавлять значки"
- "Добавлять значки установленных приложений на главный экран."
+ "Добавлять значки установленных приложений на главный экран"
"Изменить форму значков"
+ "на главном экране"
"Использовать системные настройки по умолчанию"
"Квадрат"
"Квадрат с закругленными краями"
@@ -99,6 +110,8 @@
"Скачивается \"%1$s\" (%2$s)"
"Ожидание установки \"%1$s\""
"%1$s: виджеты"
+ "Список виджетов"
+ "Список виджетов закрыт"
"Добавить на главный экран"
"Переместить элемент сюда"
"Элемент добавлен на главный экран"
@@ -114,9 +127,6 @@
"Создать папку с элементом %1$s."
"Папка создана."
"Переместить на главный экран"
- "Переместить экран влево"
- "Переместить экран вправо"
- "Экран перемещен"
"Изменить размер"
"Увеличить ширину"
"Увеличить высоту"
@@ -124,8 +134,16 @@
"Уменьшить высоту"
"Изменен размер виджета: до %1$s в ширину и %2$s в высоту"
"Ярлыки"
- "Количество ярлыков для приложения \"%2$s\": %1$d"
- "Количество ярлыков для приложения \"%3$s\": %1$d. Количество уведомлений: %2$d."
+ "Ярлыки и уведомления"
"Закрыть"
"Уведомление закрыто"
+ "Личные"
+ "Рабочие"
+ "Рабочий профиль"
+ "Приложения для работы"
+ "Рабочие приложения отмечены специальным значком. Их безопасность обеспечивает ваша организация. Для удобства перенесите эти приложения на главный экран."
+ "Управляется вашей организацией"
+ "Уведомления и приложения отключены."
+ "Закрыть"
+ "Закрыта"
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000000..10835dc5ce
--- /dev/null
+++ b/res/values-si-rLK/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "කාර්යාලය"
+ "යෙදුම ස්ථාපනය කර නැත."
+ "යෙදුම නොතිබේ"
+ "ආරක්ෂිත ආකාරය තුළ බාගන්න ලද යෙදුම් අබල කරන්න"
+ "සුරක්ෂිත ආකාරය තුළ විජටය අබල කරන ලදි"
+ "කෙටි මග ලබා ගත නොහැකිය"
+ "මුල් පිටු තිරය"
+ "අභිරුචි ක්රියා"
+ "විජට් එක ස්පර්ශ කර අහුලා ගැනීමට අල්ලාගෙන සිටින්න."
+ "විජට් එකක් අහුලා ගැනීමට හෝ අභිරුචි ක්රියා කිරීමට ඩබල් ටැප් කර අල්ලා ගෙන සිටින්න."
+ "%1$d × %2$d"
+ "පළල %1$d උස %2$d"
+ "අතින් ස්ථානගත කිරීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"
+ "ස්වයංක්රියව එක් කරන්න"
+ "යෙදුම් සොයන්න"
+ "යෙදුම් පූරණය වෙමින්…"
+ "\"%1$s\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"
+ "තව යෙදුම් සඳහා සොයන්න"
+ "දැනුම්දීම්"
+ "කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."
+ "විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."
+ "මෙම මුල් පිටු තිරය මත තවත් අවසර නැත."
+ "ප්රියතම දෑ ඇති තැටියේ තවත් ඉඩ නොමැත"
+ "යෙදුම් ලැයිස්තුව"
+ "පෞද්ගලික යෙදුම් ලැයිස්තුව"
+ "වැඩ යෙදුම් ලැයිස්තුව"
+ "මුල් පිටුව"
+ "ඉවත් කරන්න"
+ "අස්ථාපනය කරන්න"
+ "යෙදුම් තොරතුරු"
+ "ස්ථාපනය කරන්න"
+ "කෙටිමං ස්ථාපනය කරන්න"
+ "පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමකට අවසර දෙයි."
+ "මුල් පිටු සැකසීම් සහ කෙටිමං කියවන්න"
+ "මුල් පිටුවේ ඇති සැකසීම් සහ කෙටිමං කියවීමට යෙදුමකට අවසර දෙයි."
+ "මුල් පිටු සැකසීම් සහ කෙටිමං ලියන්න"
+ "මුල් පිටුවේ සැකසීම් සහ කෙටිමං ඉවත් කිරීමට යෙදුමට අවසර දෙයි."
+ "%1$s හට දුරකථන ඇමතුම් සිදු කිරීමට ඉඩ නොදේ"
+ "ගැටලු පූරණ විජට් එක"
+ "ස්ථාපනය කරන්න"
+ "මෙය පද්ධති යෙදුමක් වන අතර අස්ථාපනය කළ නොහැක."
+ "නම් නොකළ ෆෝල්ඩරය"
+ "%1$s අබල කෙරිණි"
+
+ - %1$s, දැනුම්දීම් %2$dක් ඇත
+ - %1$s, දැනුම්දීම් %2$dක් ඇත
+
+ "%2$d හි %1$d පිටුව"
+ "මුල් පිටු තිරය %2$d හි %1$d"
+ "නව මුල් පිටුව"
+ "ෆෝල්ඩරය විවෘත විය, %1$d හි %2$d"
+ "ෆෝල්ඩරය වැසීමට තට්ටු කරන්න"
+ "යළි නම් කිරීම සුරැකීමට තට්ටු කරන්න"
+ "ෆෝල්ඩරය වසා ඇත"
+ "%1$s වෙත ෆෝල්ඩරය නැවත නම් කෙරිණි"
+ "ෆෝල්ඩරය: %1$s"
+ "විජට්"
+ "වෝල්පේපර"
+ "Home සැකසීම්"
+ "ඔබගේ පරිපාලක විසින් අබල කරන ලදී"
+ "මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"
+ "දුරකථනය කරකවන විට"
+ "දැනුම්දීම් තිත්"
+ "ක්රියාත්මකයි"
+ "ක්රියාවිරහිතයි"
+ "දැනුම්දීම් ප්රවේශය අවශ්යයි"
+ "දැනුම්දීම් තිත් පෙන්වීමට, %1$s සඳහා යෙදුම් දැනුම්දීම් සබල කරන්න"
+ "සැකසීම් වෙනස් කරන්න"
+ "දැනුම් දීමේ තිත් පෙන්වන්න"
+ "මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"
+ "නව යෙදුම් සඳහා"
+ "නිරූපක හැඩය වෙනස් කරන්න"
+ "මුල් පිටු තිරය මත"
+ "පද්ධති පෙරනිමි භාවිත කරන්න"
+ "සමචතුරස්රය"
+ "හතරැස් කවය"
+ "කවය"
+ "කඳුළු බිංදුව"
+ "නිරූපක හැඩය වෙනස් කිරීම් යොදමින්"
+ "නොදනී"
+ "ඉවත් කරන්න"
+ "සොයන්න"
+ "මෙම යෙදුම ස්ථාපනය කර නොමැත"
+ "මෙම නිරුපකයට යෙදුම ස්ථාපනය කර නොමැත. ඔබට එය ඉවත් කළ හැක, හෝ යෙදුම් සඳහා සොයන්න සහ අතින් ස්ථාපනය කරන්න."
+ "%1$s බාගත කරමින්, %2$s සම්පූර්ණයි"
+ "%1$s ස්ථාපනය කිරීමට බලා සිටිමින්"
+ "%1$s විජට්"
+ "මුල් තිරය වෙත එක් කරන්න"
+ "මෙතනට අයිතමය ගෙන එන්න"
+ "අයිතමය මුල් තිරය වෙත එකතු කරන ලදි"
+ "අයිතමය ඉවත් කරන ලදි"
+ "අයිතමය ගෙනයන්න"
+ "පේළිය %1$s තීරුව %2$s වෙත ගෙන යන්න"
+ "%1$s ස්ථානය වෙත ගෙන යන්න"
+ "ප්රියතම ස්ථානය %1$s වෙත ගෙන යන්න"
+ "අයිතමය ගෙන යන ලදි"
+ "ෆෝල්ඩරය එක් කරන්න: %1$s"
+ "%1$s සමඟ ෆෝල්ඩරය වෙත එක් කරන්න"
+ "අයිතමය ෆෝඩරය වෙතට එක් කරන ලදි"
+ "මේ සමග ෆෝල්ඩරය සාදන්න: %1$s"
+ "ෆෝල්ඩරය සාදන ලදි"
+ "මුල් තිරය වෙත ගෙන යන්න"
+ "නැවත ප්රමාණගත කිරීම"
+ "පළල වැඩි කරන්න"
+ "උස වැඩි කරන්න"
+ "පළල අඩු කරන්න"
+ "උස අඩු කරන්න"
+ "විජට් පළල %1$s උස %2$s වෙත ප්රමාණකරණය කරන ලදි"
+ "කෙටිමං"
+ "%2$s සඳහා කෙටි මං %1$d"
+ "%3$s සඳහා කෙටි මං %1$dක් සහ දැනුම්දීම් %2$dක්"
+ "ඉවතලන්න"
+ "දැනුම්දීම ඉවතලන ලදී"
+ "පුද්ගලික"
+ "කාර්යාලය"
+ "කාර්යාල පැතිකඩ"
+ "මෙහි කාර්යාල යෙදුම් සොයා ගන්න"
+ "සෑම කාර්යාල යෙදුමකම ලාංඡනයක් ඇත ඇති අතර එය ඔබේ සංවිධානය මගින් සුරක්ෂිතව තබා ගනී. වඩාත් පහසු ප්රවේශයකට යෙදුම් ඔබේ මුල් පිටු තිරය වෙත ගෙන යන්න."
+ "ඔබේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"
+ "දැනුම්දීම් සහ යෙදුම් ක්රියාවිරහිතයි"
+ "වසන්න"
+ "වසා ඇත"
+
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index f6c42b2d9a..ee6112488c 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"
"තව යෙදුම් සඳහා සොයන්න"
"දැනුම්දීම්"
+ "කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."
+ "විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."
"මෙම මුල් පිටු තිරය මත තවත් අවසර නැත."
"ප්රියතම දෑ ඇති තැටියේ තවත් ඉඩ නොමැත"
"යෙදුම් ලැයිස්තුව"
+ "පෞද්ගලික යෙදුම් ලැයිස්තුව"
+ "වැඩ යෙදුම් ලැයිස්තුව"
"මුල් පිටුව"
"ඉවත් කරන්න"
"අස්ථාපනය කරන්න"
"යෙදුම් තොරතුරු"
+ "ස්ථාපනය කරන්න"
"කෙටිමං ස්ථාපනය කරන්න"
"පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමකට අවසර දෙයි."
"මුල් පිටු සැකසීම් සහ කෙටිමං කියවන්න"
@@ -59,6 +64,10 @@
"මෙය පද්ධති යෙදුමක් වන අතර අස්ථාපනය කළ නොහැක."
"නම් නොකළ ෆෝල්ඩරය"
"%1$s අබල කෙරිණි"
+
+ - %1$s, දැනුම්දීම් %2$dක් ඇත
+ - %1$s, දැනුම්දීම් %2$dක් ඇත
+
"%2$d හි %1$d පිටුව"
"මුල් පිටු තිරය %2$d හි %1$d"
"නව මුල් පිටුව"
@@ -72,19 +81,19 @@
"වෝල්පේපර"
"Home සැකසීම්"
"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"
- "දළ විශ්ලේෂණය"
"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"
"දුරකථනය කරකවන විට"
- "වත්මන් සංදර්ශක සැකසීම් කරකැවීමට සහාය නොදක්වයි"
"දැනුම්දීම් තිත්"
"ක්රියාත්මකයි"
"ක්රියාවිරහිතයි"
"දැනුම්දීම් ප්රවේශය අවශ්යයි"
"දැනුම්දීම් තිත් පෙන්වීමට, %1$s සඳහා යෙදුම් දැනුම්දීම් සබල කරන්න"
"සැකසීම් වෙනස් කරන්න"
+ "දැනුම් දීමේ තිත් පෙන්වන්න"
"මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"
"නව යෙදුම් සඳහා"
"නිරූපක හැඩය වෙනස් කරන්න"
+ "මුල් පිටු තිරය මත"
"පද්ධති පෙරනිමි භාවිත කරන්න"
"සමචතුරස්රය"
"හතරැස් කවය"
@@ -99,6 +108,8 @@
"%1$s බාගත කරමින්, %2$s සම්පූර්ණයි"
"%1$s ස්ථාපනය කිරීමට බලා සිටිමින්"
"%1$s විජට්"
+ "විජට් ලැයිස්තුව"
+ "විජට් ලැයිස්තුව වසා ඇත"
"මුල් තිරය වෙත එක් කරන්න"
"මෙතනට අයිතමය ගෙන එන්න"
"අයිතමය මුල් තිරය වෙත එකතු කරන ලදි"
@@ -114,9 +125,6 @@
"මේ සමග ෆෝල්ඩරය සාදන්න: %1$s"
"ෆෝල්ඩරය සාදන ලදි"
"මුල් තිරය වෙත ගෙන යන්න"
- "තිරය වම් පැත්තට ගෙනයන්න"
- "තිරය දකුණු පැත්තට ගෙනයන්න"
- "තිරය ගෙන යන ලදි"
"නැවත ප්රමාණගත කිරීම"
"පළල වැඩි කරන්න"
"උස වැඩි කරන්න"
@@ -124,8 +132,16 @@
"උස අඩු කරන්න"
"විජට් පළල %1$s උස %2$s වෙත ප්රමාණකරණය කරන ලදි"
"කෙටිමං"
- "%2$s සඳහා කෙටි මං %1$d"
- "%3$s සඳහා කෙටි මං %1$dක් සහ දැනුම්දීම් %2$dක්"
+ "කෙටි මං සහ දැනුම්දීම්"
"ඉවතලන්න"
"දැනුම්දීම ඉවතලන ලදී"
+ "පුද්ගලික"
+ "කාර්යාලය"
+ "කාර්යාල පැතිකඩ"
+ "මෙහි කාර්යාල යෙදුම් සොයා ගන්න"
+ "සෑම කාර්යාල යෙදුමකම ලාංඡනයක් ඇත ඇති අතර එය ඔබේ සංවිධානය මගින් සුරක්ෂිතව තබා ගනී. වඩාත් පහසු ප්රවේශයකට යෙදුම් ඔබේ මුල් පිටු තිරය වෙත ගෙන යන්න."
+ "ඔබේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"
+ "දැනුම්දීම් සහ යෙදුම් ක්රියාවිරහිතයි"
+ "වසන්න"
+ "වසා ඇත"
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 4dbc407b9c..649aecc8a8 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -40,13 +40,18 @@
"Nenašli sa žiadne aplikácie zodpovedajúce dopytu %1$s"
"Hľadať ďalšie aplikácie"
"Upozornenia"
+ "Skratku pridáte pridržaním."
+ "Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."
"Na tejto ploche už nie je miesto"
"Na paneli Obľúbené položky už nie je miesto"
"Zoznam aplikácií"
+ "Zoznam osobných aplikácií"
+ "Zoznam pracovných aplikácií"
"Domovská stránka"
"Odstrániť"
"Odinštalovať"
"Info o aplikácii"
+ "Inštalovať"
"inštalovať odkazy"
"Povoľuje aplikácii pridať odkazy bez zásahu používateľa."
"čítanie nastavení a odkazov plochy"
@@ -59,6 +64,12 @@
"Toto je systémová aplikácia a nedá sa odinštalovať."
"Nepomenovaný priečinok"
"Aplikácia %1$s je deaktivovaná"
+
+ - Aplikácia %1$s má %2$d upozornenia
+ - Aplikácia %1$s má %2$d upozornenia
+ - Aplikácia %1$s má %2$d upozornení
+ - Aplikácia %1$s má %2$d upozornenie
+
"Stránka %1$d z %2$d"
"Plocha %1$d z %2$d"
"Nová stránka plochy"
@@ -70,21 +81,21 @@
"Priečinok: %1$s"
"Miniaplikácie"
"Tapety"
- "Nastavenia služby Home"
+ "Nastavenia Home"
"Zakázané vaším správcom"
- "Prehľad"
"Povoliť otáčanie plochy"
"Pri otočení telefónu"
- "Aktuálne nastavenie obrazovky nepovoľuje otáčanie"
"Bodky upozornení"
"Zapnuté"
"Vypnuté"
"Vyžaduje sa prístup k upozorneniam"
"Ak chcete, aby sa zobrazovali bodky upozornení, zapnite upozornenia aplikácie %1$s"
"Zmeniť nastavenia"
+ "Zobrazovať bodky upozornení"
"Pridať ikonu na plochu"
"Pri inštalácii novej aplikácie"
"Zmeniť tvar ikony"
+ "na ploche"
"Použiť predvolené nastavenie systému"
"Štvorec"
"Okrúhly štvorec"
@@ -99,6 +110,8 @@
"Sťahuje sa aplikácia %1$s. Stiahnuté: %2$s"
"Aplikácia %1$s čaká na inštaláciu"
"Miniaplikácie %1$s"
+ "Zoznam miniaplikácií"
+ "Zoznam miniaplikácií je zavretý"
"Pridať na plochu"
"Presunúť položku sem"
"Položka bola pridaná na plochu"
@@ -114,9 +127,6 @@
"Vytvoriť priečinok pomocou: %1$s"
"Priečinok bol vytvorený"
"Presunúť na plochu"
- "Presunúť obrazovku doľava"
- "Presunúť obrazovku doprava"
- "Obrazovka bola posunutá"
"Zmeniť veľkosť"
"Zvýšiť šírku"
"Zväčšiť výšku"
@@ -124,8 +134,16 @@
"Znížiť výšku"
"Veľkosť miniaplikácie bola zmenená na %1$s x %2$s (šírka x výška)"
"Skratky"
- "Počet skratiek aplikácie %2$s: %1$d"
- "Odkazy (%1$d) a upozornenia (%2$d) pre aplikáciu %3$s"
+ "Odkazy a upozornenia"
"Zavrieť"
"Upozornenie bolo zavreté"
+ "Osobné"
+ "Pracovné"
+ "Pracovný profil"
+ "Tu nájdete pracovné aplikácie"
+ "Všetky pracovné aplikácie majú štítok a sú bezpečne uchovávané vašou organizáciou. Ak chcete mať k aplikáciám ľahší prístup, presuňte ich na plochu."
+ "Spravované vašou organizáciou"
+ "Upozornenia a aplikácie sú vypnuté"
+ "Zavrieť"
+ "Zavreté"
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 0b7d36ef8b..aa3bc4fc57 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -40,13 +40,18 @@
"Ni aplikacij, ki bi ustrezale poizvedbi »%1$s«"
"Iskanje več aplikacij"
"Obvestila"
+ "Pridržite bližnjico, da jo izberete."
+ "Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri."
"Na tem začetnem zaslonu ni več prostora."
"V vrstici za priljubljene ni več prostora"
"Seznam aplikacij"
+ "Seznam osebnih aplikacij"
+ "Seznam delovnih aplikacij"
"Začetni zaslon"
"Odstrani"
"Odstrani"
"Podatki o aplikaciji"
+ "Namesti"
"namestitev bližnjic"
"Aplikaciji dovoli dodajanje bližnjic brez posredovanja uporabnika."
"branje nastavitev in bližnjic na začetnem zaslonu"
@@ -59,6 +64,12 @@
"To je sistemska aplikacija in je ni mogoče odstraniti."
"Neimenovana mapa"
"Aplikacija %1$s je onemogočena"
+
+ - Aplikacija %1$s ima %2$d obvestilo
+ - Aplikacija %1$s ima %2$d obvestili
+ - Aplikacija %1$s ima %2$d obvestila
+ - Aplikacija %1$s ima %2$d obvestil
+
"Stran %1$d od %2$d"
"Začetni zaslon %1$d od %2$d"
"Nova stran na začetnem zaslonu"
@@ -72,19 +83,19 @@
"Ozadja"
"Nastavitve začetnega zaslona"
"Onemogočil skrbnik."
- "Pregled"
"Omogočanje sukanja začetnega zaslona"
"Ko se telefon zasuka"
- "Trenutna nastavitev zaslona ne dovoljuje sukanja"
"Obvestilne pike"
"Vklopljeno"
"Izklopljeno"
"Potreben je dostop do obvestil"
"Za prikaz obvestilnih pik vklopite obvestila aplikacije %1$s"
"Spremeni nastavitve"
+ "Pokaži obvestilne pike"
"Dodaj ikono na začetni zaslon"
"Za nove aplikacije"
"Spremeni obliko ikon"
+ "na začetnem zaslonu"
"Uporabi privzeto nastavitev sistema"
"Kvadrat"
"Zaobljen kvadrat"
@@ -99,6 +110,8 @@
"Prenašanje aplikacije %1$s; preneseno %2$s"
"Aplikacija %1$s čaka na namestitev"
"Pripomočki za %1$s"
+ "Seznam pripomočkov"
+ "Seznam pripomočkov se je zaprl"
"Dodajanje na začetni zaslon"
"Premik elementa sem"
"Element je bil dodan na začetni zaslon"
@@ -114,9 +127,6 @@
"Ustvarjanje mape s tem: %1$s"
"Mapa je ustvarjena"
"Premik na začetni zaslon"
- "Premik zaslona levo"
- "Premika zaslona desno"
- "Zaslon je bil premaknjen"
"Spreminjanje velikosti"
"Povečanje širine"
"Povečanje višine"
@@ -124,8 +134,16 @@
"Zmanjšanje višine"
"Velikost pripomočka je bila spremenjena na %1$s širine in %2$s višine"
"Bližnjice"
- "Št. bližnjic za aplikacijo %2$s: %1$d"
- "Bližnjice (%1$d) in obvestila (%2$d) aplikacije %3$s"
+ "Bližnjice in obvestila"
"Opusti"
"Obvestilo je bilo opuščeno"
+ "Osebno"
+ "Služba"
+ "Delovni profil"
+ "Tukaj poiščite delovne aplikacije"
+ "Vsaka delovna aplikacija ima značko. Za varnost teh aplikacij skrbi vaša organizacija. Za preprostejši dostop premaknite aplikacije na začetni zaslon."
+ "Upravlja vaša organizacija"
+ "Obvestila in aplikacije – izklopljeno"
+ "Zapri"
+ "Zaprto"
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000000..82cc42a169
--- /dev/null
+++ b/res/values-sq-rAL/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Nisësi3"
+
+ "Puna"
+ "Aplikacioni nuk është i instaluar."
+ "Aplikacioni nuk mundësohet"
+ "Aplikacioni i shkarkuar është i çaktivizuar në modalitetin e sigurt"
+ "Miniaplikacionet janë të çaktivizuara në modalitetin e sigurt"
+ "Shkurtorja nuk është e disponueshme"
+ "Ekrani bazë"
+ "Veprimet e personalizuara"
+ "Prek dhe mbaj shtypur për të zgjedhur një miniaplikacion."
+ "Prek dy herë dhe mbaj shtypur për të zgjedhur një miniaplikacion ose për të përdorur veprimet e personalizuara."
+ "%1$d × %2$d"
+ "%1$d i gjerë me %2$d i lartë"
+ "Prek dhe mbaj të shtypur për të vendosur në mënyrë manuale"
+ "Shto automatikisht"
+ "Kërko për aplikacione"
+ "Po ngarkon aplikacionet..."
+ "Nuk u gjet asnjë aplikacion që përputhet me \"%1$s\""
+ "Kërko për më shumë aplikacione"
+ "Njoftimet"
+ "Prek dhe mbaj prekur për të zgjedhur një shkurtore."
+ "Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."
+ "Nuk ka më hapësirë në këtë ekran bazë."
+ "Nuk ka më hapësirë në tabakanë \"Të preferuarat\""
+ "Lista e aplikacioneve"
+ "Lista e aplikacioneve personale"
+ "Lista e aplikacioneve të punës"
+ "Faqja kryesore"
+ "Hiqe"
+ "Çinstalo"
+ "Informacion mbi aplikacionin"
+ "Instalo"
+ "instalo shkurtore"
+ "Lejon një aplikacion të shtojë shkurtore pa ndërhyrjen e përdoruesit."
+ "lexo cilësimet dhe shkurtoret e ekranit bazë"
+ "Lejon aplikacionin të lexojë cilësimet dhe shkurtoret në ekranin bazë."
+ "shkruaj cilësimet dhe shkurtoret e ekranit bazë"
+ "Lejon aplikacionin të ndryshojë cilësimet dhe shkurtoret në ekranin bazë."
+ "%1$s nuk lejohet të kryejë telefonata"
+ "Problem në ngarkimin e miniaplikacionit"
+ "Konfiguro"
+ "Ky është aplikacion sistemi dhe nuk mund të çinstalohet."
+ "Dosje e paemërtuar"
+ "%1$s u çaktivizua"
+
+ - %1$s, ka %2$d njoftime
+ - %1$s, ka %2$d njoftime
+
+ "Faqja: %1$d nga gjithsej %2$d"
+ "Ekrani bazë: %1$d nga gjithsej %2$d"
+ "Faqja e ekranit të ri kryesor"
+ "Dosja u hap, %1$d me %2$d"
+ "Trokit për të mbyllur dosjen"
+ "Trokit për të ruajtur riemërtimin"
+ "Dosja u mbyll"
+ "Dosja u riemërtua në %1$s"
+ "Dosja: %1$s"
+ "Miniaplikacionet"
+ "Imazhet e sfondit"
+ "Cilësimet e Home"
+ "Çaktivizuar nga administratori"
+ "Lejo rrotullimin e ekranit kryesor"
+ "Kur telefoni rrotullohet"
+ "Pikat e njoftimeve"
+ "Aktiv"
+ "Joaktiv"
+ "Nevojitet qasja në njoftime"
+ "Për të shfaqur \"Pikat e njoftimeve\", aktivizo njoftimet e aplikacionit për %1$s"
+ "Ndrysho cilësimet"
+ "Shfaq pikat e njoftimeve"
+ "Shto ikonë në ekranin bazë"
+ "Për aplikacionet e reja"
+ "Ndrysho formën e ikonës"
+ "në ekranin bazë"
+ "Përdor parazgjedhjen e sistemit"
+ "Katror"
+ "Katror me kënde të rrumbullakëta"
+ "Rreth"
+ "Pikë loti"
+ "Po zbatohen ndryshimet e formës së ikonës"
+ "I panjohur"
+ "Hiq"
+ "Kërko"
+ "Aplikacioni nuk është i instaluar"
+ "Aplikacioni për këtë ikonë nuk është i instaluar. Mund ta heqësh ose të kërkosh aplikacionin dhe ta instalosh atë në mënyrë manuale."
+ "%1$s po shkarkohet, %2$s të përfunduara"
+ "%1$s po pret të instalohet"
+ "Miniaplikacionet e %1$s"
+ "Shto në Ekranin bazë"
+ "Zhvendose artikullin këtu"
+ "Artikulli u shtua tek ekrani bazë"
+ "Artikulli u hoq"
+ "Zhvendose artikullin"
+ "Zhvendos te rreshti %1$s, kolona %2$s"
+ "Zhvendos te pozicioni %1$s"
+ "Zhvendos te pozicioni %1$s i preferencave"
+ "Artikulli u zhvendos"
+ "Shto te dosja: %1$s"
+ "Shto te dosja me %1$s"
+ "Artikulli u shtua te dosja"
+ "Krijo një dosje me: %1$s"
+ "Dosja u krijua"
+ "Zhvendose në Ekranin bazë"
+ "Ndrysho madhësinë"
+ "Rrit gjerësinë"
+ "Rrit lartësinë"
+ "Zvogëlo gjerësinë"
+ "Zvogëlo lartësinë"
+ "Madhësia e miniaplikacionit u ndryshua me gjerësinë %1$s dhe lartësinë %2$s"
+ "Shkurtoret"
+ "%1$d shkurtesa për %2$s"
+ "%1$d shkurtore dhe %2$d njoftime për %3$s"
+ "Hiqe"
+ "Njoftimi u hoq"
+ "Personale"
+ "Punë"
+ "Profili i punës"
+ "Gjej këtu aplikacionet e punës"
+ "Secili aplikacion pune ka një distinktiv dhe mbahet i sigurt nga organizata jote. Zhvendosi aplikacionet e punës në ekranin tënd kryesor për qasje më të lehtë."
+ "Menaxhohet nga organizata jote"
+ "Njoftimet dhe aplikacionet janë joaktive"
+ "Mbyll"
+ "Mbyllur"
+
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 3e6afee609..8cf0a8198f 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -40,13 +40,18 @@
"Nuk u gjet asnjë aplikacion që përputhet me \"%1$s\""
"Kërko për më shumë aplikacione"
"Njoftimet"
+ "Prek dhe mbaj prekur për të zgjedhur një shkurtore."
+ "Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."
"Nuk ka më hapësirë në këtë ekran bazë."
"Nuk ka më hapësirë në tabakanë \"Të preferuarat\""
"Lista e aplikacioneve"
+ "Lista e aplikacioneve personale"
+ "Lista e aplikacioneve të punës"
"Faqja kryesore"
"Hiqe"
"Çinstalo"
"Informacion mbi aplikacionin"
+ "Instalo"
"instalo shkurtore"
"Lejon një aplikacion të shtojë shkurtore pa ndërhyrjen e përdoruesit."
"lexo cilësimet dhe shkurtoret e ekranit bazë"
@@ -59,6 +64,10 @@
"Ky është aplikacion sistemi dhe nuk mund të çinstalohet."
"Dosje e paemërtuar"
"%1$s u çaktivizua"
+
+ - %1$s, ka %2$d njoftime
+ - %1$s, ka %2$d njoftime
+
"Faqja: %1$d nga gjithsej %2$d"
"Ekrani bazë: %1$d nga gjithsej %2$d"
"Faqja e ekranit të ri kryesor"
@@ -72,20 +81,20 @@
"Imazhet e sfondit"
"Cilësimet e Home"
"Çaktivizuar nga administratori"
- "Përmbledhje"
"Lejo rrotullimin e ekranit kryesor"
"Kur telefoni rrotullohet"
- "Cilësimi aktuali i afishimit nuk lejon rrotullimin"
"Pikat e njoftimeve"
"Aktiv"
"Joaktiv"
"Nevojitet qasja në njoftime"
"Për të shfaqur \"Pikat e njoftimeve\", aktivizo njoftimet e aplikacionit për %1$s"
"Ndrysho cilësimet"
+ "Shfaq pikat e njoftimeve"
"Shto ikonë në ekranin bazë"
"Për aplikacionet e reja"
"Ndrysho formën e ikonës"
- "Përdor parazgjedhjen e sisteit"
+ "në ekranin bazë"
+ "Përdor parazgjedhjen e sistemit"
"Katror"
"Katror me kënde të rrumbullakëta"
"Rreth"
@@ -99,6 +108,8 @@
"%1$s po shkarkohet, %2$s të përfunduara"
"%1$s po pret të instalohet"
"Miniaplikacionet e %1$s"
+ "Lista e miniaplikacioneve"
+ "Lista e miniaplikacioneve u mbyll"
"Shto në Ekranin bazë"
"Zhvendose artikullin këtu"
"Artikulli u shtua tek ekrani bazë"
@@ -114,9 +125,6 @@
"Krijo një dosje me: %1$s"
"Dosja u krijua"
"Zhvendose në Ekranin bazë"
- "Zhvendose ekranin në të majtë"
- "Zhvendose ekranin në të djathtë"
- "Ekrani u zhvendos"
"Ndrysho madhësinë"
"Rrit gjerësinë"
"Rrit lartësinë"
@@ -124,8 +132,16 @@
"Zvogëlo lartësinë"
"Madhësia e miniaplikacionit u ndryshua me gjerësinë %1$s dhe lartësinë %2$s"
"Shkurtoret"
- "%1$d shkurtesa për %2$s"
- "%1$d shkurtore dhe %2$d njoftime për %3$s"
+ "Shkurtoret dhe njoftimet"
"Hiqe"
"Njoftimi u hoq"
+ "Personale"
+ "Punë"
+ "Profili i punës"
+ "Gjej këtu aplikacionet e punës"
+ "Secili aplikacion pune ka një distinktiv dhe mbahet i sigurt nga organizata jote. Zhvendosi aplikacionet e punës në ekranin tënd kryesor për qasje më të lehtë."
+ "Menaxhohet nga organizata jote"
+ "Njoftimet dhe aplikacionet janë joaktive"
+ "Mbyll"
+ "Mbyllur"
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index f41e02d33f..42522a579b 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -40,13 +40,18 @@
"Није пронађена ниједна апликација за „%1$s“"
"Претражи још апликација"
"Обавештења"
+ "Додирните и задржите да бисте изабрали пречицу."
+ "Двапут додирните и задржите да бисте изабрали пречицу или користите прилагођене радње."
"Нема више простора на овом почетном екрану."
"Нема више простора на траци Омиљено"
"Листа апликација"
+ "Листа личних апликација"
+ "Листа пословних апликација"
"Почетна"
"Уклони"
"Деинсталирај"
"Информ. о апликацији"
+ "Инсталирај"
"инсталирање пречица"
"Дозвољава апликацији да додаје пречице без интервенције корисника."
"читање подешавања и пречица на почетном екрану"
@@ -59,6 +64,11 @@
"Ово је системска апликација и не може да се деинсталира."
"Неименовани директоријум"
"Апликација %1$s је онемогућена"
+
+ - %1$s има %2$d обавештење
+ - %1$s има %2$d обавештења
+ - %1$s има %2$d обавештења
+
"%1$d. страница од %2$d"
"%1$d. почетни екран од %2$d"
"Нова страница почетног екрана"
@@ -72,19 +82,19 @@
"Позадине"
"Подешавања почетног екрана"
"Администратор је онемогућио"
- "Преглед"
"Дозволи ротацију почетног екрана"
"Када се телефон ротира"
- "Актуелно подешавање приказа не дозвољава ротацију"
"Тачке за обавештења"
"Укључено"
"Искључено"
"Потребан је приступ за обавештења"
"Да бисте приказали тачке за обавештења, укључите обавештења за апликацију %1$s"
"Промените подешавања"
+ "Приказуј тачке за обавештења"
"Додај икону на почетни екран"
"За нове апликације"
"Промените облик икона"
+ "на почетном екрану"
"Користи подразумевано системско подешавање"
"Квадрат"
"Заобљени квадрат"
@@ -99,6 +109,8 @@
"%1$s се преузима, завршено је %2$s"
"%1$s чека на инсталирање"
"Виџети за %1$s"
+ "Листа виџета"
+ "Листа виџета је затворена"
"Додај на почетни екран"
"Премести ставку овде"
"Ставка је додата на почетни екран"
@@ -114,9 +126,6 @@
"Направите директоријум са: %1$s"
"Директоријум је направљен"
"Премести на почетни екран"
- "Помери екран улево"
- "Помери екран удесно"
- "Екран је померен"
"Промени величину"
"Повећај ширину"
"Повећај висину"
@@ -124,8 +133,16 @@
"Смањи висину"
"Величина виџета је промењена на ширину %1$s и висину %2$s"
"Пречице"
- "%1$d пречице(а) за %2$s"
- "Пречице (%1$d) и обавештења (%2$d) за %3$s"
+ "Пречице и обавештења"
"Одбаци"
"Обавештење је одбачено"
+ "Личне"
+ "Пословне"
+ "Профил за Work"
+ "Пронађите пословне апликације овде"
+ "Свака пословна апликација има значку и штити је ваша организација. Преместите апликације на почетни екран да бисте им лакше приступали."
+ "Овим управља организација"
+ "Обавештења и апликације су искључени"
+ "Затвори"
+ "Затворено"
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 6c598ff5dc..957a4cb2d4 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -40,13 +40,18 @@
"Inga appar som matchar %1$s hittades"
"Sök efter fler appar"
"Aviseringar"
+ "Tryck länge om du vill ta upp en genväg."
+ "Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder."
"Det finns inte plats för mer på den här startskärmen."
"Favoritfältet är fullt"
"Applista"
+ "Listan Personliga appar"
+ "Listan Jobbappar"
"Startskärm"
"Ta bort"
"Avinstallera"
"Info om appen"
+ "Installera"
"installera genvägar"
"Tillåter att en app lägger till genvägar utan åtgärd från användaren."
"läsa inställningar och genvägar för startsidan"
@@ -59,6 +64,10 @@
"Det här är en systemapp som inte kan avinstalleras."
"Namnlös mapp"
"%1$s har inaktiverats"
+
+ - %1$s har %2$d aviseringar
+ - %1$s har %2$d avisering
+
"Sidan %1$d av %2$d"
"Startskärmen %1$d av %2$d"
"Ny sida på startskärmen"
@@ -70,21 +79,21 @@
"Mapp: %1$s"
"Widgetar"
"Bakgrunder"
- "Inställningar för startsidan"
+ "Startinställningar"
"Inaktiverat av administratören"
- "Översikt"
"Tillåt rotering av startskärmen"
"När mobilen vrids"
- "Rotering tillåts inte i de nuvarande skärminställningarna"
"Aviseringsprickar"
"På"
"Av"
"Åtkomst till aviseringar krävs"
"Aktivera appaviseringar för %1$s om du vill att aviseringsprickar ska visas"
"Ändra inställningar"
+ "Visa aviseringsprickar"
"Lägg till ikonen på startskärmen"
"För nya appar"
"Ändra form på ikoner"
+ "på startskärmen"
"Använd systemstandard"
"Kvadrat"
"Kvirkel"
@@ -99,6 +108,8 @@
"%1$s laddas ned, %2$s klart"
"%1$s väntar på installation"
"%1$s widgetar"
+ "Widgetlista"
+ "Widgetslistan har stängts"
"Lägg till på startskärmen"
"Flytta objekt hit"
"Objektet har lagts till på startskärmen"
@@ -114,9 +125,6 @@
"Skapa mapp med: %1$s"
"Mappen har skapats"
"Flytta till startskärmen"
- "Flytta skärmen till vänster"
- "Flytta skärmen till höger"
- "Skärmen har flyttats"
"Ändra storlek"
"Öka bredden"
"Öka höjden"
@@ -124,8 +132,16 @@
"Minska höjden"
"Widgetens storlek har ändrats till: bredd %1$s, höjd %2$s"
"Genvägar"
- "%1$d genvägar för %2$s"
- "%3$s har %1$d genvägar och %2$d aviseringar"
+ "Genvägar och aviseringar"
"Ignorera"
"Aviseringen togs bort"
+ "Privat"
+ "Arbete"
+ "Jobbprofil"
+ "Här hittar du jobbappar"
+ "Alla jobbappar har ett märke och organisationen ser till att de är skyddade. Flytta apparna till startskärmen så kommer du åt dem lättare."
+ "Hanteras av organisationen"
+ "Aviseringar och appar är inaktiverade"
+ "Stäng"
+ "Stängd"
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 3de28e011d..faa40a71c2 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -30,7 +30,7 @@
"Skrini ya kwanza"
"Vitendo maalum"
"Gusa na ushikilie ili kuteua wijeti."
- "Gonga mara mbili na ushikilie ile uchague wijeti au utumie vitendo maalum."
+ "Gusa mara mbili na ushikilie ile uchague wijeti au utumie vitendo maalum."
"%1$d × %2$d"
"Upana wa %1$d na kimo cha %2$d"
"Gusa na ushikilie ili uweke mwenyewe"
@@ -40,13 +40,18 @@
"Haikupata programu zozote zinazolingana na \"%1$s\""
"Tafuta programu zaidi"
"Arifa"
+ "Gusa na ushikilie ili uchague njia ya mkato."
+ "Gusa mara mbili na ushikilie ili uchague njia ya mkato au utumie vitendo maalum."
"Hakuna nafasi katika skrini hii ya Mwanzo."
"Hakuna nafasi zaidi katika treya ya Vipendeleo"
"Orodha ya programu"
+ "Orodha ya programu za binafsi"
+ "Orodha ya programu za kazini"
"Mwanzo"
"Ondoa"
"Ondoa"
"Maelezo ya programu"
+ "Sakinisha"
"kuweka njia za mkato"
"Huruhusu programu kuongeza njia za mkato bila mtumiaji kuingilia kati."
"soma mipangilio ya Mwanzo na njia za mkato"
@@ -59,35 +64,39 @@
"Hii ni programu ya mfumo na haiwezi kuondolewa."
"Folda isiyo na jina"
"%1$s imezimwa"
+
+ - %1$s, ina arifa %2$d
+ - %1$s, ina arifa %2$d
+
"Ukurasa%1$d wa %2$d"
"Ukurasa mpya wa skrini ya kwanza"
"Folda imefunguliwa, %1$d kwa %2$d"
- "Gonga ili ufunge folda"
- "Gonga ili ubadilishe jina"
+ "Gusa ili ufunge folda"
+ "Gusa ili ubadilishe jina"
"Folda imefungwa"
"Folda imebadilishwa jina kuwa %1$s"
"Folda: %1$s"
"Wijeti"
"Mandhari"
- "Mipangilio ya ukurasa wa mwanzo"
+ "Mipangilio ya mwanzo"
"Imezimwa na msimamizi wako"
- "Muhtasari"
"Ruhusu kuzungusha skrini ya Kwanza"
"Simu inapozungushwa"
- "Mipangilio ya sasa ya sehemu ya Onyesho hairuhusu kuzungusha"
"Vitone vya arifa"
"Imewashwa"
"Imezimwa"
"Inahitaji idhini ya kufikia arifa"
"Ili kuonyesha Vitone vya Arifa, washa kipengele cha arifa za programu katika %1$s"
"Badilisha mipangilio"
+ "Onyesha kitone cha arifa"
"Ongeza aikoni kwenye Skrini ya kwanza"
"Kwa ajili ya programu mpya"
"Badilisha umbo la aikoni"
- "Tumia umbo chaguo-msingi la mfumo"
+ "kwenye Skrini ya mwanzo"
+ "Tumia umbo chaguomsingi la mfumo"
"Mraba"
"Mstatili wenye pembe duara"
"Mduara"
@@ -97,10 +106,12 @@
"Ondoa"
"Tafuta"
"Programu hii haijasakinishwa"
- "Programu ya ikoni hii haijasakinishwa. Unaweza kuiondoa, au utafute programu na uisakinishe wewe mwenyewe."
+ "Programu ya aikoni hii haijasakinishwa. Unaweza kuiondoa, au utafute programu na uisakinishe wewe mwenyewe."
"%1$s inapakuliwa, %2$s imekamilika"
"%1$s inasubiri kusakinisha"
"Wijeti za %1$s"
+ "Orodha ya wijeti"
+ "Orodha ya wijeti imefungwa"
"Ongeza kwenye skrini ya Kwanza"
"Hamishia kipengee hapa"
"Kipengee kimeongezwa kwenye skrini ya kwanza"
@@ -116,9 +127,6 @@
"Unda folda ukitumia: %1$s"
"Folda imeundwa"
"Hamishia Skrini ya kwanza"
- "Sogeza skrini kushoto"
- "Sogeza skrini kulia"
- "Skrini imesogezwa"
"Badilisha ukubwa"
"Ongeza upana"
"Ongeza urefu"
@@ -126,8 +134,16 @@
"Punguza urefu"
"Wijeti imepunguzwa hadi upana %1$s urefu %2$s"
"Njia za mkato"
- "Njia %1$d za mkato za %2$s"
- "Njia %1$d za mkato na arifa %2$d za %3$s"
+ "Arifa na njia za mkato"
"Ondoa"
"Arifa imeondolewa"
+ "Binafsi"
+ "Kazini"
+ "Wasifu wa kazini"
+ "Pata programu za kazi hapa"
+ "Kila programu ya kazi ina beji na hulindwa na shirika lako. Hamishia programu kwenye skrini yako ya kwanza ili uzifikie kwa urahisi."
+ "Inasimamiwa na shirika lako"
+ "Vipenge vya arifa na programu vimezimwa"
+ "Funga"
+ "Imefungwa"
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index 72894dcf37..f322e9f31b 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -26,7 +26,6 @@
- true
- true
- ?android:attr/textColorSecondary
- - @layout/search_container_all_apps
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
new file mode 100644
index 0000000000..a51247c2de
--- /dev/null
+++ b/res/values-ta-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "பணியிடம்"
+ "பயன்பாடு நிறுவப்படவில்லை."
+ "பயன்பாடு இல்லை"
+ "இறக்கிய பயன்பாடு பாதுகாப்பு முறையில் முடக்கப்பட்டது"
+ "பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன"
+ "குறுக்குவழி இல்லை"
+ "முகப்புத் திரை"
+ "தனிப்பயன் செயல்கள்"
+ "விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் பிடிக்கவும்."
+ "விட்ஜெட்டைத் தேர்ந்தெடுக்க இருமுறை தட்டிப் பிடிக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."
+ "%1$d × %2$d"
+ "%1$d அகலத்திற்கு %2$d உயரம்"
+ "நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"
+ "தானாகவே சேர்"
+ "பயன்பாடுகளில் தேடுக"
+ "பயன்பாடுகளை ஏற்றுகிறது…"
+ "\"%1$s\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"
+ "கூடுதல் பயன்பாடுகளைத் தேடு"
+ "அறிவிப்புகள்"
+ "ஷார்ட்கட்டைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்."
+ "ஷார்ட்கட்டைச் சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் (அ) தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."
+ "முகப்புத் திரையில் இடமில்லை."
+ "பிடித்தவை ட்ரேயில் இடமில்லை"
+ "பயன்பாடுகளின் பட்டியல்"
+ "தனிப்பட்ட ஆப்ஸ் பட்டியல்"
+ "பணி ஆப்ஸ் பட்டியல்"
+ "முகப்பு"
+ "அகற்று"
+ "நிறுவல் நீக்கு"
+ "பயன்பாட்டுத் தகவல்"
+ "நிறுவு"
+ "குறுக்குவழிகளை நிறுவுதல்"
+ "பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது."
+ "முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"
+ "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."
+ "முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்"
+ "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."
+ "ஃபோன் அழைப்புகள் செய்ய, %1$s அனுமதிக்கப்படவில்லை"
+ "விட்ஜெட்டை ஏற்றுவதில் சிக்கல்"
+ "அமைவு"
+ "இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது."
+ "பெயரிடப்படாத கோப்புறை"
+ "%1$s முடக்கப்பட்டது"
+
+ - %1$s பயன்பாட்டில், %2$d அறிவிப்புகள் வந்துள்ளன
+ - %1$s பயன்பாட்டில், %2$d அறிவிப்பு வந்துள்ளது
+
+ "பக்கம் %1$d / %2$d"
+ "முகப்புத் திரை %1$d of %2$d"
+ "புதிய முகப்புத் திரை பக்கம்"
+ "திறக்கப்பட்டக் கோப்புறை, %1$d x %2$d"
+ "கோப்புறையை மூட, தட்டவும்"
+ "மாற்றிய பெயரைச் சேமிக்க, தட்டவும்"
+ "கோப்புறை மூடப்பட்டது"
+ "கோப்புறை %1$s என மறுபெயரிடப்பட்டது"
+ "கோப்புறை: %1$s"
+ "ஷார்ட்கட்ஸ்"
+ "வால்பேப்பர்கள்"
+ "முகப்பு அமைப்புகள்"
+ "உங்கள் நிர்வாகி முடக்கியுள்ளார்"
+ "முகப்புத் திரை சுழற்சியை அனுமதி"
+ "மொபைலைச் சுழற்றும் போது"
+ "அறிவிப்புப் புள்ளிகள்"
+ "ஆன்"
+ "முடக்கப்பட்டுள்ளது"
+ "அறிவிப்பிற்கான அணுகல் தேவை"
+ "அறிவிப்புப் புள்ளிகளைக் காட்ட, %1$s இன் பயன்பாட்டு அறிவிப்புகளை இயக்கவும்"
+ "அமைப்புகளை மாற்று"
+ "அறிவிப்புப் புள்ளிகளைக் காட்டு"
+ "முகப்புத் திரையில் ஐகானைச் சேர்"
+ "புதிய பயன்பாடுகளுக்கு"
+ "ஐகான் வடிவத்தை மாற்று"
+ "முகப்புத் திரையில்"
+ "அமைப்பின் இயல்புநிலையைப் பயன்படுத்து"
+ "சதுரம்"
+ "சதுரவட்டம்"
+ "வட்டம்"
+ "கண்ணீர்துளி"
+ "ஐகான் வடிவத்தை மாற்றுகிறது"
+ "தெரியாதது"
+ "அகற்று"
+ "தேடு"
+ "பயன்பாடு நிறுவப்படவில்லை"
+ "ஐகானுக்கான பயன்பாடு நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்."
+ "%1$sஐப் பதிவிறக்குகிறது, %2$s முடிந்தது"
+ "%1$sஐ நிறுவுவதற்காகக் காத்திருக்கிறது"
+ "%1$s விட்ஜெட்டுகள்"
+ "முகப்புத் திரையில் சேர்"
+ "இங்கு நகர்த்து"
+ "முகப்புத் திரையில் சேர்க்கப்பட்டது"
+ "அகற்றப்பட்டது"
+ "நகர்த்து"
+ "%1$s வரிசை, %2$s நெடுவரிசைக்கு நகர்த்து"
+ "நிலை %1$sக்கு நகர்த்து"
+ "விரும்பும் நிலை %1$sக்கு நகர்த்து"
+ "உருப்படி நகர்த்தப்பட்டது"
+ "இந்தக் கோப்புறையில் சேர்க்கும்: %1$s"
+ "%1$s உள்ள கோப்புறையில் சேர்க்கும்"
+ "கோப்புறையில் உருப்படி சேர்க்கப்பட்டது"
+ "இதனுடன் கோப்புறையை உருவாக்கும்: %1$s"
+ "கோப்புறை உருவாக்கப்பட்டது"
+ "முகப்புத் திரைக்கு நகர்த்து"
+ "அளவு மாற்று"
+ "அகலத்தை அதிகரி"
+ "உயரத்தை அதிகரி"
+ "அகலத்தைக் குறை"
+ "உயரத்தைக் குறை"
+ "அகலம் %1$s மற்றும் உயரம் %2$sக்கு விட்ஜெட் அளவு மாற்றப்பட்டது"
+ "குறுக்குவழிகள்"
+ "%2$sக்கான %1$d குறுக்குவழிகள்"
+ "%3$s பயன்பாட்டிற்கான %1$d குறுக்குவழிகளும் %2$d அறிவிப்புகளும் உள்ளன"
+ "நிராகரி"
+ "அறிவிப்பு நிராகரிக்கப்பட்டது"
+ "தனிப்பட்டவை"
+ "பணி"
+ "பணி விவரம்"
+ "பணி ஆப்ஸை இங்கு காணலாம்"
+ "ஒவ்வொரு பணிப் பயன்பாடும் ஒரு பேட்ஜைக் கொண்டிருக்கும். இவை, ஆப்ஸ் உங்கள் நிறுவனத்தால் பாதுகாப்பாக வைக்கப்பட்டுள்ளன என்பதைக் குறிக்கின்றன. இந்த ஆப்ஸை எளிதாக அணுக, முகப்புத் திரைக்கு நகர்த்திக்கொள்ளவும்."
+ "உங்கள் நிறுவனம் நிர்வகிக்கிறது"
+ "ஆப்ஸும் அறிவிப்புகளும் ஆஃப் செய்யப்பட்டுள்ளன"
+ "மூடுக"
+ "மூடப்பட்டது"
+
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 1d92581a05..983a0d1f2d 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"
"கூடுதல் பயன்பாடுகளைத் தேடு"
"அறிவிப்புகள்"
+ "ஷார்ட்கட்டைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்."
+ "ஷார்ட்கட்டைச் சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் (அ) தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."
"முகப்புத் திரையில் இடமில்லை."
"பிடித்தவை ட்ரேயில் இடமில்லை"
"பயன்பாடுகளின் பட்டியல்"
+ "தனிப்பட்ட ஆப்ஸ் பட்டியல்"
+ "பணி ஆப்ஸ் பட்டியல்"
"முகப்பு"
"அகற்று"
"நிறுவல் நீக்கு"
"பயன்பாட்டுத் தகவல்"
+ "நிறுவு"
"குறுக்குவழிகளை நிறுவுதல்"
"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது."
"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"
@@ -59,6 +64,10 @@
"இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது."
"பெயரிடப்படாத கோப்புறை"
"%1$s முடக்கப்பட்டது"
+
+ - %1$s பயன்பாட்டில், %2$d அறிவிப்புகள் வந்துள்ளன
+ - %1$s பயன்பாட்டில், %2$d அறிவிப்பு வந்துள்ளது
+
"பக்கம் %1$d / %2$d"
"முகப்புத் திரை %1$d of %2$d"
"புதிய முகப்புத் திரை பக்கம்"
@@ -72,19 +81,19 @@
"வால்பேப்பர்கள்"
"முகப்பு அமைப்புகள்"
"உங்கள் நிர்வாகி முடக்கியுள்ளார்"
- "மேலோட்டப் பார்வை"
"முகப்புத் திரை சுழற்சியை அனுமதி"
"மொபைலைச் சுழற்றும் போது"
- "தற்போதைய திரை அமைப்பு சுழற்றுவதை அனுமதிக்கவில்லை"
"அறிவிப்புப் புள்ளிகள்"
- "இயக்கப்பட்டுள்ளது"
+ "ஆன்"
"முடக்கப்பட்டுள்ளது"
"அறிவிப்பிற்கான அணுகல் தேவை"
"அறிவிப்புப் புள்ளிகளைக் காட்ட, %1$s இன் பயன்பாட்டு அறிவிப்புகளை இயக்கவும்"
"அமைப்புகளை மாற்று"
+ "அறிவிப்புப் புள்ளிகளைக் காட்டு"
"முகப்புத் திரையில் ஐகானைச் சேர்"
"புதிய பயன்பாடுகளுக்கு"
"ஐகான் வடிவத்தை மாற்று"
+ "முகப்புத் திரையில்"
"அமைப்பின் இயல்புநிலையைப் பயன்படுத்து"
"சதுரம்"
"சதுரவட்டம்"
@@ -99,6 +108,10 @@
"%1$sஐப் பதிவிறக்குகிறது, %2$s முடிந்தது"
"%1$sஐ நிறுவுவதற்காகக் காத்திருக்கிறது"
"%1$s விட்ஜெட்டுகள்"
+
+
+
+
"முகப்புத் திரையில் சேர்"
"இங்கு நகர்த்து"
"முகப்புத் திரையில் சேர்க்கப்பட்டது"
@@ -114,9 +127,6 @@
"இதனுடன் கோப்புறையை உருவாக்கும்: %1$s"
"கோப்புறை உருவாக்கப்பட்டது"
"முகப்புத் திரைக்கு நகர்த்து"
- "திரையை இடப்புறம் நகர்த்து"
- "திரையை வலப்புறம் நகர்த்து"
- "திரை நகர்த்தப்பட்டது"
"அளவு மாற்று"
"அகலத்தை அதிகரி"
"உயரத்தை அதிகரி"
@@ -124,8 +134,16 @@
"உயரத்தைக் குறை"
"அகலம் %1$s மற்றும் உயரம் %2$sக்கு விட்ஜெட் அளவு மாற்றப்பட்டது"
"குறுக்குவழிகள்"
- "%2$sக்கான %1$d குறுக்குவழிகள்"
- "%3$s பயன்பாட்டிற்கான %1$d குறுக்குவழிகளும் %2$d அறிவிப்புகளும் உள்ளன"
+ "ஷார்ட்கட்கள் மற்றும் அறிவிப்புகள்"
"நிராகரி"
"அறிவிப்பு நிராகரிக்கப்பட்டது"
+ "தனிப்பட்டவை"
+ "பணி"
+ "பணி விவரம்"
+ "பணி ஆப்ஸை இங்கு காணலாம்"
+ "ஒவ்வொரு பணிப் பயன்பாடும் ஒரு பேட்ஜைக் கொண்டிருக்கும். இவை, ஆப்ஸ் உங்கள் நிறுவனத்தால் பாதுகாப்பாக வைக்கப்பட்டுள்ளன என்பதைக் குறிக்கின்றன. இந்த ஆப்ஸை எளிதாக அணுக, முகப்புத் திரைக்கு நகர்த்திக்கொள்ளவும்."
+ "உங்கள் நிறுவனம் நிர்வகிக்கிறது"
+ "ஆப்ஸும் அறிவிப்புகளும் ஆஃப் செய்யப்பட்டுள்ளன"
+ "மூடுக"
+ "மூடப்பட்டது"
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
new file mode 100644
index 0000000000..bffb1a8700
--- /dev/null
+++ b/res/values-te-rIN/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "కార్యాలయం"
+ "యాప్ ఇన్స్టాల్ చేయబడలేదు."
+ "యాప్ అందుబాటులో లేదు"
+ "డౌన్లోడ్ చేసిన యాప్ సురక్షిత మోడ్లో నిలిపివేయబడింది"
+ "సురక్షిత మోడ్లో విడ్జెట్లు నిలిపివేయబడ్డాయి"
+ "షార్ట్కట్ అందుబాటులో లేదు"
+ "హోమ్ స్క్రీన్"
+ "అనుకూల చర్యలు"
+ "విడ్జెట్ను ఎంచుకోవడానికి తాకి & నొక్కి పెట్టండి."
+ "విడ్జెట్ను ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి, ఉంచండి."
+ "%1$d × %2$d"
+ "%1$d వెడల్పు X %2$d ఎత్తు"
+ "మాన్యువల్గా ఉంచడానికి నొక్కి & పట్టుకోండి"
+ "స్వయంచాలకంగా జోడించు"
+ "అప్లికేషన్లను శోధించండి"
+ "అప్లికేషన్లను లోడ్ చేస్తోంది…"
+ "\"%1$s\"కి సరిపోలే అప్లికేషన్లేవీ కనుగొనబడలేదు"
+ "మరిన్ని యాప్ల కోసం వెతుకు"
+ "నోటిఫికేషన్లు"
+ "షార్ట్కట్ని ఎంచుకోవడం కోసం నొక్కి, పట్టుకోండి."
+ "రెండుసార్లు నొక్కి, పట్టుకోవడం ద్వారా షార్ట్కట్ని ఎంచుకోండి లేదా అనుకూల చర్యలను ఉపయోగించండి."
+ "ఈ హోమ్ స్క్రీన్లో ఖాళీ లేదు."
+ "ఇష్టమైనవి ట్రేలో ఖాళీ లేదు"
+ "అనువర్తనాల జాబితా"
+ "వ్యక్తిగత యాప్ల జాబితా"
+ "కార్యాలయ యాప్ల జాబితా"
+ "హోమ్"
+ "తీసివేయి"
+ "అన్ఇన్స్టాల్ చేయి"
+ "యాప్ సమాచారం"
+ "ఇన్స్టాల్ చేయండి"
+ "సత్వరమార్గాలను ఇన్స్టాల్ చేయడం"
+ "వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."
+ "హోమ్ సెట్టింగ్లు మరియు సత్వరమార్గాలను చదవడం"
+ "హోమ్లో సెట్టింగ్లు మరియు సత్వరమార్గాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."
+ "హోమ్ సెట్టింగ్లు మరియు సత్వరమార్గాలను వ్రాయడం"
+ "హోమ్లో సెట్టింగ్లు మరియు సత్వరమార్గాలను మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."
+ "ఫోన్ కాల్లను చేసేందుకు %1$sకి అనుమతి లేదు"
+ "విడ్జెట్ను లోడ్ చేయడంలో సమస్య"
+ "సెటప్ చేయి"
+ "ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్ఇన్స్టాల్ చేయడం సాధ్యపడదు."
+ "పేరు లేని ఫోల్డర్"
+ "%1$s నిలిపివేయబడింది"
+
+ - %1$s %2$d నోటిఫికేషన్లను కలిగి ఉన్నారు
+ - %1$s %2$d నోటిఫికేషన్ను కలిగి ఉన్నారు
+
+ "%2$dలో %1$dవ పేజీ"
+ "%2$dలో %1$dవ హోమ్ స్క్రీన్"
+ "కొత్త హోమ్ స్క్రీన్ పేజీ"
+ "ఫోల్డర్ తెరవబడింది, %1$d X %2$d"
+ "ఫోల్డర్ను మూసివేయడానికి నొక్కండి"
+ "పేరు మార్పును సేవ్ చేయడానికి నొక్కండి"
+ "ఫోల్డర్ మూసివేయబడింది"
+ "ఫోల్డర్ పేరు %1$sగా మార్చబడింది"
+ "ఫోల్డర్: %1$s"
+ "విడ్జెట్లు"
+ "వాల్పేపర్లు"
+ "హోమ్ సెట్టింగ్లు"
+ "మీ నిర్వాహకులు నిలిపివేసారు"
+ "హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"
+ "ఫోన్ను తిప్పినప్పుడు"
+ "నోటిఫికేషన్ డాట్లు"
+ "ఆన్"
+ "ఆఫ్"
+ "నోటిఫికేషన్ యాక్సెస్ అవసరం"
+ "నోటిఫికేషన్ డాట్లను చూపించడానికి %1$sకు యాప్ నోటిఫికేషన్లను ఆన్ చేయండి"
+ "సెట్టింగ్లను మార్చు"
+ "నోటిఫికేషన్ డాట్లను చూపుతుంది"
+ "హోమ్ స్క్రీన్కి చిహ్నాన్ని జోడించు"
+ "కొత్త యాప్ల కోసం"
+ "చిహ్న ఆకారాన్ని మార్చు"
+ "హోమ్ స్క్రీన్పై"
+ "సిస్టమ్ డిఫాల్ట్ను ఉపయోగించండి"
+ "చతురస్రం"
+ "చతురస్రాకార వృత్తం"
+ "వృత్తం"
+ "కన్నీటి చుక్క"
+ "చిహ్న ఆకార మార్పులను వర్తింపజేస్తోంది"
+ "తెలియదు"
+ "తీసివేయి"
+ "వెతుకు"
+ "ఈ యాప్ ఇన్స్టాల్ చేయబడలేదు"
+ "ఈ చిహ్నం యొక్క యాప్ ఇన్స్టాల్ చేయబడలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ యాప్ కోసం శోధించి దాన్ని మాన్యువల్గా ఇన్స్టాల్ చేయవచ్చు."
+ "%1$s డౌన్లోడ్ అవుతోంది, %2$s పూర్తయింది"
+ "%1$s ఇన్స్టాల్ కావడానికి వేచి ఉంది"
+ "%1$s విడ్జెట్లు"
+ "హోమ్ స్క్రీన్కు జోడించు"
+ "అంశాన్ని ఇక్కడికి తరలించు"
+ "అంశం హోమ్స్క్రీన్కి జోడించబడింది"
+ "అంశం తీసివేయబడింది"
+ "అంశాన్ని తరలించు"
+ "అడ్డు వరుస %1$s నిలువు వరుస %2$sకి తరలించు"
+ "%1$sవ స్థానానికి తరలించు"
+ "ఇష్టమైనవిలో %1$sవ స్థానానికి తరలించు"
+ "అంశం తరలించబడింది"
+ "ఈ ఫోల్డర్కి జోడించండి: %1$s"
+ "%1$s గల ఫోల్డర్కు జోడించు"
+ "అంశం ఫోల్డర్కు జోడించబడింది"
+ "ఈ పేరుతో ఫోల్డర్ను సృష్టించండి: %1$s"
+ "ఫోల్డర్ సృష్టించబడింది"
+ "హోమ్స్క్రీన్కు తరలించు"
+ "పరిమాణం మార్చు"
+ "వెడల్పును పెంచు"
+ "ఎత్తును పెంచు"
+ "వెడల్పును తగ్గించు"
+ "ఎత్తును తగ్గించు"
+ "విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది"
+ "సత్వరమార్గాలు"
+ "%2$s కోసం %1$d సత్వరమార్గాలు"
+ "%3$s కోసం %1$d సత్వరమార్గాలు మరియు %2$d నోటిఫికేషన్లు"
+ "తీసివేయి"
+ "నోటిఫికేషన్ తీసివేయబడింది"
+ "వ్యక్తిగతం"
+ "కార్యాలయం"
+ "కార్యాలయ ప్రొఫైల్"
+ "కార్యాలయ యాప్లను ఇక్కడ కనుగొనండి"
+ "ప్రతి కార్యాలయ యాప్కు బ్యాడ్జ్ ఉంది మరియు మీ సంస్థ ద్వారా సురక్షితంగా ఉంచబడుతుంది. సులభ యాక్సెస్ కోసం యాప్లను మీ హోమ్ స్క్రీన్కి తరలించండి."
+ "మీ సంస్థ ద్వారా నిర్వహించబడతాయి"
+ "నోటిఫికేషన్లు మరియు యాప్లు ఆఫ్ చేయబడ్డాయి"
+ "మూసివేయి"
+ "మూసివేయబడింది"
+
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 6c6669938b..a18d6496a6 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -26,7 +26,7 @@
"యాప్ అందుబాటులో లేదు"
"డౌన్లోడ్ చేసిన యాప్ సురక్షిత మోడ్లో నిలిపివేయబడింది"
"సురక్షిత మోడ్లో విడ్జెట్లు నిలిపివేయబడ్డాయి"
- "సత్వరమార్గం అందుబాటులో లేదు"
+ "షార్ట్కట్ అందుబాటులో లేదు"
"హోమ్ స్క్రీన్"
"అనుకూల చర్యలు"
"విడ్జెట్ను ఎంచుకోవడానికి తాకి & నొక్కి పెట్టండి."
@@ -38,15 +38,20 @@
"అప్లికేషన్లను శోధించండి"
"అప్లికేషన్లను లోడ్ చేస్తోంది…"
"\"%1$s\"కి సరిపోలే అప్లికేషన్లేవీ కనుగొనబడలేదు"
- "మరిన్ని అనువర్తనాల కోసం శోధించు"
+ "మరిన్ని యాప్ల కోసం వెతుకు"
"నోటిఫికేషన్లు"
+ "షార్ట్కట్ని ఎంచుకోవడం కోసం నొక్కి, పట్టుకోండి."
+ "రెండుసార్లు నొక్కి, పట్టుకోవడం ద్వారా షార్ట్కట్ని ఎంచుకోండి లేదా అనుకూల చర్యలను ఉపయోగించండి."
"ఈ హోమ్ స్క్రీన్లో ఖాళీ లేదు."
"ఇష్టమైనవి ట్రేలో ఖాళీ లేదు"
"అనువర్తనాల జాబితా"
+ "వ్యక్తిగత యాప్ల జాబితా"
+ "కార్యాలయ యాప్ల జాబితా"
"హోమ్"
"తీసివేయి"
"అన్ఇన్స్టాల్ చేయి"
- "అనువర్తన సమాచారం"
+ "యాప్ సమాచారం"
+ "ఇన్స్టాల్ చేయండి"
"సత్వరమార్గాలను ఇన్స్టాల్ చేయడం"
"వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."
"హోమ్ సెట్టింగ్లు మరియు సత్వరమార్గాలను చదవడం"
@@ -59,6 +64,10 @@
"ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్ఇన్స్టాల్ చేయడం సాధ్యపడదు."
"పేరు లేని ఫోల్డర్"
"%1$s నిలిపివేయబడింది"
+
+ - %1$s %2$d నోటిఫికేషన్లను కలిగి ఉన్నారు
+ - %1$s %2$d నోటిఫికేషన్ను కలిగి ఉన్నారు
+
"%2$dలో %1$dవ పేజీ"
"%2$dలో %1$dవ హోమ్ స్క్రీన్"
"కొత్త హోమ్ స్క్రీన్ పేజీ"
@@ -72,19 +81,19 @@
"వాల్పేపర్లు"
"హోమ్ సెట్టింగ్లు"
"మీ నిర్వాహకులు నిలిపివేసారు"
- "స్థూలదృష్టి"
"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"
"ఫోన్ను తిప్పినప్పుడు"
- "ప్రస్తుత డిస్ప్లే సెట్టింగ్ భ్రమణాన్ని అనుమతించలేదు"
"నోటిఫికేషన్ డాట్లు"
"ఆన్"
"ఆఫ్"
"నోటిఫికేషన్ యాక్సెస్ అవసరం"
"నోటిఫికేషన్ డాట్లను చూపించడానికి %1$sకు యాప్ నోటిఫికేషన్లను ఆన్ చేయండి"
"సెట్టింగ్లను మార్చు"
+ "నోటిఫికేషన్ డాట్లను చూపుతుంది"
"హోమ్ స్క్రీన్కి చిహ్నాన్ని జోడించు"
- "కొత్త అనువర్తనాల కోసం"
+ "కొత్త యాప్ల కోసం"
"చిహ్న ఆకారాన్ని మార్చు"
+ "హోమ్ స్క్రీన్పై"
"సిస్టమ్ డిఫాల్ట్ను ఉపయోగించండి"
"చతురస్రం"
"చతురస్రాకార వృత్తం"
@@ -93,12 +102,16 @@
"చిహ్న ఆకార మార్పులను వర్తింపజేస్తోంది"
"తెలియదు"
"తీసివేయి"
- "శోధించు"
+ "వెతుకు"
"ఈ యాప్ ఇన్స్టాల్ చేయబడలేదు"
"ఈ చిహ్నం యొక్క యాప్ ఇన్స్టాల్ చేయబడలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ యాప్ కోసం శోధించి దాన్ని మాన్యువల్గా ఇన్స్టాల్ చేయవచ్చు."
"%1$s డౌన్లోడ్ అవుతోంది, %2$s పూర్తయింది"
"%1$s ఇన్స్టాల్ కావడానికి వేచి ఉంది"
"%1$s విడ్జెట్లు"
+
+
+
+
"హోమ్ స్క్రీన్కు జోడించు"
"అంశాన్ని ఇక్కడికి తరలించు"
"అంశం హోమ్స్క్రీన్కి జోడించబడింది"
@@ -114,9 +127,6 @@
"ఈ పేరుతో ఫోల్డర్ను సృష్టించండి: %1$s"
"ఫోల్డర్ సృష్టించబడింది"
"హోమ్స్క్రీన్కు తరలించు"
- "స్క్రీన్ను ఎడమవైపుకి జరుపు"
- "స్క్రీన్ను కుడివైపుకి జరుపు"
- "స్క్రీన్ జరపబడింది"
"పరిమాణం మార్చు"
"వెడల్పును పెంచు"
"ఎత్తును పెంచు"
@@ -124,8 +134,16 @@
"ఎత్తును తగ్గించు"
"విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది"
"సత్వరమార్గాలు"
- "%2$s కోసం %1$d సత్వరమార్గాలు"
- "%3$s కోసం %1$d సత్వరమార్గాలు మరియు %2$d నోటిఫికేషన్లు"
+ "షార్ట్కట్లు మరియు నోటిఫికేషన్లు"
"తీసివేయి"
"నోటిఫికేషన్ తీసివేయబడింది"
+ "వ్యక్తిగతం"
+ "కార్యాలయం"
+ "కార్యాలయ ప్రొఫైల్"
+ "కార్యాలయ యాప్లను ఇక్కడ కనుగొనండి"
+ "ప్రతి కార్యాలయ యాప్కు బ్యాడ్జ్ ఉంది మరియు మీ సంస్థ ద్వారా సురక్షితంగా ఉంచబడుతుంది. సులభ యాక్సెస్ కోసం యాప్లను మీ హోమ్ స్క్రీన్కి తరలించండి."
+ "మీ సంస్థ ద్వారా నిర్వహించబడతాయి"
+ "నోటిఫికేషన్లు మరియు యాప్లు ఆఫ్ చేయబడ్డాయి"
+ "మూసివేయి"
+ "మూసివేయబడింది"
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index b370099889..2da32de6fd 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -40,13 +40,18 @@
"ไม่พบแอปที่ตรงกับ \"%1$s\""
"ค้นหาแอปเพิ่มเติม"
"การแจ้งเตือน"
+ "แตะค้างไว้เพื่อเลือกทางลัด"
+ "แตะสองครั้งค้างไว้เพื่อเลือกทางลัดหรือใช้การกระทำที่กำหนดเอง"
"ไม่มีที่ว่างในหน้าจอหลักนี้"
"ไม่มีพื้นที่เหลือในถาดรายการโปรด"
"รายชื่อแอป"
+ "รายการแอปส่วนตัว"
+ "รายการแอปสำหรับทำงาน"
"หน้าแรก"
"นำออก"
"ถอนการติดตั้ง"
"ข้อมูลแอป"
+ "ติดตั้ง"
"ติดตั้งทางลัด"
"อนุญาตให้แอปเพิ่มทางลัดโดยไม่ต้องให้ผู้ใช้จัดการ"
"อ่านการตั้งค่าและทางลัดหน้าแรกแล้ว"
@@ -59,6 +64,10 @@
"นี่เป็นแอประบบและไม่สามารถถอนการติดตั้งได้"
"โฟลเดอร์ที่ไม่มีชื่อ"
"ปิดใช้ %1$s"
+
+ - %1$s มีการแจ้งเตือน %2$d รายการ
+ - %1$s มีการแจ้งเตือน %2$d รายการ
+
"หน้า %1$d จาก %2$d"
"หน้าจอหลัก %1$d จาก %2$d"
"หน้าใหม่ในหน้าจอหลัก"
@@ -72,19 +81,19 @@
"วอลเปเปอร์"
"การตั้งค่าหน้าแรก"
"ปิดใช้โดยผู้ดูแลระบบ"
- "ภาพรวม"
"อนุญาตให้หมุนหน้าจอหลัก"
"เมื่อหมุนโทรศัพท์"
- "การตั้งค่าการแสดงผลปัจจุบันไม่อนุญาตให้มีการหมุน"
"จุดแจ้งเตือน"
"เปิด"
"ปิด"
"ต้องได้รับสิทธิ์เข้าถึงการแจ้งเตือน"
"เปิดการแจ้งเตือนแอปของ %1$s เพื่อแสดงจุดแจ้งเตือน"
"เปลี่ยนการตั้งค่า"
+ "แสดงจุดแจ้งเตือน"
"เพิ่มไอคอนในหน้าจอหลัก"
"สำหรับแอปใหม่"
"เปลี่ยนรูปร่างไอคอน"
+ "ในหน้าจอหลัก"
"ใช้ค่าเริ่มต้นของระบบ"
"สี่เหลี่ยมจัตุรัส"
"สี่เหลี่ยมขอบมน"
@@ -99,6 +108,8 @@
"กำลังดาวน์โหลด %1$s เสร็จแล้ว %2$s"
"%1$s กำลังรอติดตั้ง"
"วิดเจ็ตของ %1$s"
+ "รายการวิดเจ็ต"
+ "ปิดรายการวิดเจ็ตแล้ว"
"เพิ่มลงในหน้าแรก"
"ย้ายรายการมาที่นี่"
"เพิ่มรายการไปยังหน้าจอหลักแล้ว"
@@ -114,9 +125,6 @@
"สร้างโฟลเดอร์ด้วย: %1$s"
"สร้างโฟลเดอร์แล้ว"
"ย้ายไปที่หน้าจอหลัก"
- "เลื่อนหน้าจอไปทางซ้าย"
- "เลื่อนหน้าจอไปทางขวา"
- "ย้ายหน้าจอแล้ว"
"ปรับขนาด"
"เพิ่มความกว้าง"
"เพิ่มความสูง"
@@ -124,8 +132,16 @@
"ลดความสูง"
"ปรับขนาดของวิดเจ็ตเป็นกว้าง %1$s สูง %2$s แล้ว"
"ทางลัด"
- "%1$d ทางลัดสำหรับ %2$s"
- "ทางลัด %1$d รายการและการแจ้งเตือน %2$d รายการสำหรับ %3$s"
+ "ทางลัดและการแจ้งเตือน"
"ปิด"
"ปิดการแจ้งเตือนแล้ว"
+ "ส่วนตัว"
+ "งาน"
+ "โปรไฟล์งาน"
+ "หาแอปงานที่นี่"
+ "แอปงานแต่ละแอปมีป้ายและได้รับการรักษาความปลอดภัยจากองค์กรของคุณ ย้ายแอปไปยังหน้าจอหลักเพื่อให้เข้าถึงได้ง่ายขึ้น"
+ "จัดการโดยองค์กร"
+ "ปิดการแจ้งเตือนและแอปอยู่"
+ "ปิด"
+ "ปิด"
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 54135c9d58..68d52591f0 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -40,13 +40,18 @@
"Walang nahanap na app na tumutugma sa \"%1$s\""
"Maghanap ng higit pang mga app"
"Mga Notification"
+ "Pindutin nang matagal para kumuha ng shortcut."
+ "I-double tap nang matagal para kumuha ng shortcut o gumamit ng mga custom na pagkilos."
"Wala nang lugar sa Home screen na ito."
"Wala nang lugar sa tray ng Mga Paborito"
"Listahan ng mga app"
+ "Listahan ng mga personal na app"
+ "Listahan ng mga app sa trabaho"
"Home"
"Alisin"
"I-uninstall"
"Impormasyon ng app"
+ "I-install"
"i-install ang mga shortcut"
"Pinapayagan ang isang app na magdagdag ng mga shortcut nang walang panghihimasok ng user."
"basahin ang mga setting at shortcut ng Home"
@@ -59,6 +64,10 @@
"Isa itong app ng system at hindi maaaring i-uninstall."
"Walang Pangalang Folder"
"Naka-disable ang %1$s"
+
+ - May %2$d notification ang %1$s
+ - May %2$d na notification ang %1$s
+
"Pahina %1$d ng %2$d"
"Home screen %1$d ng %2$d"
"Bagong page ng home screen"
@@ -72,19 +81,19 @@
"Mga Wallpaper"
"Mga setting ng Home"
"Na-disable ng iyong admin"
- "Pangkalahatang-ideya"
"Payagan ang pag-rotate ng Home screen"
"Kailan maro-rotate ang telepono"
- "Hindi pinahihintulutan ng kasalukuyang setting ng Display ang pag-rotate"
"Mga notification dot"
"Naka-on"
"Naka-off"
"Kinakailangan ng access sa notification"
"Upang ipakita ang Mga Notification Dot, i-on ang mga notification ng app para sa %1$s"
"Baguhin ang mga setting"
+ "Ipakita ang mga notification dot"
"Idagdag ang icon sa Home screen"
"Para sa mga bagong app"
"Baguhin ang hugis ng icon"
+ "sa Home screen"
"Gamitin ang default ng system"
"Parisukat"
"Squircle"
@@ -99,6 +108,8 @@
"Dina-download na ang %1$s, tapos na ang %2$s"
"Hinihintay nang mag-install ang %1$s"
"Mga widget ng %1$s"
+ "Listahan ng mga widget"
+ "Nakasara ang listahan ng mga widget"
"Idagdag sa Home screen"
"Ilipat ang item dito"
"Naidagdag sa home screen ang item"
@@ -114,9 +125,6 @@
"Gumawa ng folder na may: %1$s"
"Nagawa ang folder"
"Ilipat sa Home screen"
- "Ilipat sa kaliwa ang screen"
- "Ilipat sa kanan ang screen"
- "Nailipat ang screen"
"I-resize"
"Dagdagan ang lapad"
"Dagdagan ang taas"
@@ -124,8 +132,16 @@
"Bawasan ang taas"
"Na-resize ang widget sa lapad %1$s taas %2$s"
"Mga Shortcut"
- "%1$d (na) shortcut para sa %2$s"
- "%1$d (na) shortcut at %2$d (na) notification para sa %3$s"
+ "Mga shortcut at notification"
"I-dismiss"
"Na-dismiss ang notification"
+ "Personal"
+ "Trabaho"
+ "Profile sa trabaho"
+ "Maghanap ng mga app para sa trabaho rito"
+ "Ang bawat app para sa trabaho ay may badge at pinapanatiling ligtas ng iyong organisasyon. Ilipat ang mga app sa iyong Home screen para mas madaling ma-access."
+ "Pinamamahalaan ng iyong organisasyon"
+ "Naka-off ang mga notification at app"
+ "Isara"
+ "Nakasara"
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index cb8b50af20..af121f237f 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" ile eşleşen uygulama bulunamadı"
"Başka uygulamalar ara"
"Bildirimler"
+ "Kısayol seçmek için dokunun ve basılı tutun."
+ "Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."
"Bu Ana ekranda yer kalmadı."
"Favoriler tepsisinde başka yer kalmadı"
"Uygulamalar listesi"
+ "Kişisel uygulamalar listesi"
+ "İş uygulamaları listesi"
"Ana ekran"
"Kaldır"
"Yüklemeyi kaldır"
"Uygulama bilgileri"
+ "Yükle"
"kısayolları yükle"
"Uygulamaya, kullanıcı müdahalesi olmadan kısayol ekleme izni verir."
"Ana ekran ayarlarını ve kısayollarını oku"
@@ -59,6 +64,10 @@
"Bu bir sistem uygulamasıdır ve yüklemesi kaldırılamaz."
"Adsız Klasör"
"%1$s devre dışı"
+
+ - %1$s uygulamasının %2$d bildirimi var
+ - %1$s uygulamasının %2$d bildirimi var
+
"Sayfa %1$d / %2$d"
"Ana ekran %1$d / %2$d"
"Yeni ana ekran sayfası"
@@ -72,19 +81,19 @@
"Duvar Kağıtları"
"Ana ekran ayarları"
"Yöneticiniz tarafından devre dışı bırakıldı"
- "Genel bakış"
"Ana ekranı döndürmeye izin ver"
"Telefon döndürüldüğünde"
- "Mevcut Ekran ayarı, döndürmeye izin vermiyor"
"Bildirim noktaları"
"Açık"
"Kapalı"
"Bildirim erişimi gerekli"
"Bildirim Noktaları\'nı göstermek için %1$s uygulamasının bildirimlerini açın"
"Ayarları değiştir"
+ "Bildirim noktalarını göster"
"Ana ekrana simge ekle"
"Yeni uygulamalar için"
"Simge şeklini değiştir"
+ "Ana ekranda"
"Sistem varsayılanını kullan"
"Kare"
"Kare-daire"
@@ -99,6 +108,8 @@
"%1$s indiriliyor, %2$s tamamlandı"
"%1$s uygulaması yüklenmek için bekliyor"
"%1$s widget\'ları"
+ "Widget listesi"
+ "Widget listesi kapalı"
"Ana ekrana ekle"
"Öğeyi buraya taşı"
"Öğe ana ekrana eklendi"
@@ -114,9 +125,6 @@
"Şu öğeyle klasör oluştur: %1$s"
"Klasör oluşturuldu"
"Ana ekrana taşı"
- "Ekranı sola taşı"
- "Ekranı sağa taşı"
- "Ekran taşındı"
"Yeniden boyutlandır"
"Genişliği artır"
"Yüksekliği artır"
@@ -124,8 +132,16 @@
"Yüksekliği azalt"
"Widget, %1$s genişlik ve %2$s yükseklik değerine yeniden boyutlandırıldı"
"Kısayollar"
- "%2$s için %1$d kısayol"
- "%3$s için %1$d kısayol ve %2$d bildirim"
+ "Kısayollar ve bildirimler"
"Kapat"
"Bildirim kapatıldı"
+ "Kişisel"
+ "İş"
+ "İş profili"
+ "İş uygulamalarını burada bulabilirsiniz"
+ "Her iş uygulamasında, uygulama güvenliğinin kuruluşunuz tarafından sağlandığını gösteren bir rozet bulunur. Daha kolay erişim için uygulamaları Ana ekranınıza taşıyın."
+ "Kuruluşunuz tarafından yönetiliyor"
+ "Bildirimler ve uygulamalar kapalı"
+ "Kapat"
+ "Kapalı"
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index a9e010921f..305c9aaef7 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -40,13 +40,18 @@
"Немає додатків для запиту \"%1$s\""
"Шукати ще додатки"
"Сповіщення"
+ "Натисніть і втримуйте, щоб вибрати ярлик."
+ "Двічі натисніть і втримуйте, щоб вибрати ярлик, або виконайте іншу дію."
"На цьому головному екрані більше немає місця."
"В області \"Вибране\" немає місця"
"Список додатків"
+ "Список особистих додатків"
+ "Список робочих додатків"
"Головний екран"
"Видалити"
"Видалити"
"Про додаток"
+ "Установити"
"створення ярликів"
"Дозволяє програмі самостійно додавати ярлики."
"читати налаштування та ярлики головного екрана"
@@ -59,6 +64,12 @@
"Це системна програма, її неможливо видалити."
"Папка без назви"
"%1$s вимкнено"
+
+ - Додаток %1$s має %2$d сповіщення
+ - Додаток %1$s має %2$d сповіщення
+ - Додаток %1$s має %2$d сповіщень
+ - Додаток %1$s має %2$d сповіщення
+
"Сторінка %1$d з %2$d"
"Головний екран %1$d з %2$d"
"Нова сторінка головного екрана"
@@ -72,19 +83,19 @@
"Фонові малюнки"
"Налаштування Home"
"Вимкнув адміністратор"
- "Огляд"
"Дозволити обертання головного екрана"
"Коли телефон обертається"
- "Поточні налаштування дисплея не підтримують обертання"
"Значки сповіщень"
"Увімкнено"
"Вимкнено"
"Потрібен доступ до сповіщень"
"Щоб показувати значки сповіщень, увімкніть сповіщення в додатку %1$s"
"Змінити налаштування"
+ "Показувати значки сповіщень"
"Додати значок на головний екран"
"Для нових додатків"
"Змінити форму значка"
+ "на головному екрані"
"Використовувати налаштування системи за умовчанням"
"Квадрат"
"Квадрат із заокругленими кутами"
@@ -99,6 +110,8 @@
"%1$s завантажується, %2$s"
"%1$s очікує на завантаження"
"Віджети додатка %1$s"
+ "Список віджетів"
+ "Список віджектів закрито"
"Додати на головний екран"
"Перемістити елемент сюди"
"Елемент додано на головний екран"
@@ -114,9 +127,6 @@
"Створити папку з: %1$s"
"Папку створено"
"Перемістити на головний екран"
- "Перемістити екран ліворуч"
- "Перемістити екран праворуч"
- "Екран переміщено"
"Змінити розміри"
"Збільшити ширину"
"Збільшити висоту"
@@ -124,8 +134,16 @@
"Зменшити висоту"
"Розміри віджета змінено на %1$s завширшки та %2$s заввишки"
"Ярлики"
- "Ярликів для додатка %2$s: %1$d"
- "Ярлики (%1$d) і сповіщення (%2$d) додатка %3$s"
+ "Ярлики та сповіщення"
"Закрити"
"Сповіщення закрито"
+ "Особисті додатки"
+ "Робочі додатки"
+ "Робочий профіль"
+ "Робочі додатки містяться тут"
+ "Кожний робочий додаток має значок і перебуває під захистом організації. Перенесіть додатки на головний екран, щоб швидко запускати їх."
+ "Профілем керує ваша організація"
+ "Сповіщення та додатки вимкнено"
+ "Закрити"
+ "Закрито"
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
new file mode 100644
index 0000000000..77aa0a1eb5
--- /dev/null
+++ b/res/values-ur-rPK/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "دفتری"
+ "ایپ انسٹال نہیں ہے۔"
+ "ایپ دستیاب نہیں ہے"
+ "ڈاؤن لوڈ کردہ ایپ کو محفوظ وضع میں غیر فعال کر دیا گیا"
+ "ویجیٹس کو محفوظ وضع میں غیر فعال کر دیا گیا"
+ "شارٹ کٹ دستیاب نہیں ہے"
+ "ہوم اسکرین"
+ "حسب ضرورت کارروائیاں"
+ "کوئی ویجیٹ منتخب کرنے کیلئے ٹچ کریں اور پکڑے رہیں۔"
+ "کوئی ویجٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور پکڑے رکھیں۔"
+ "%1$d × %2$d"
+ "%1$d چوڑا اور %2$d اونچا"
+ "دستی طور پر رکھنے کیلئے & ٹچ کرکے ہولڈ کریں"
+ "خود کار طور پر شامل کریں"
+ "ایپس تلاش کریں"
+ "ایپس لوڈ کی جا رہی ہیں…"
+ "\"%1$s\" سے مماثل کوئی ایپس نہیں ملیں"
+ "مزید ایپس تلاش کریں"
+ "اطلاعات"
+ "ایک شارٹ کٹ منتخب کرنے کیلئے ٹچ کر کے دبائے رکھیں۔"
+ "ایک شارٹ کٹ منتخب کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔"
+ "اس ہوم اسکرین پر مزید کوئی گنجائش نہیں ہے۔"
+ "پسندیدہ ٹرے میں مزید کوئی گنجائش نہیں ہے"
+ "ایپس کی فہرست"
+ "ذاتی ایپس کی فہرست"
+ "دفتری ایپس کی فہرست"
+ "ہوم"
+ "ہٹائیں"
+ "اَن انسٹال کریں"
+ "ایپ کی معلومات"
+ "انسٹال کریں"
+ "شارٹ کٹس انسٹال کریں"
+ "کسی ایپ کو صارف کی مداخلت کے بغیر شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"
+ "ہوم ترتیبات اور شارٹ کٹس کو پڑھیں"
+ "ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو پڑھنے کی اجازت دیتا ہے۔"
+ "ہوم ترتیبات اور شارٹ کٹس کو لکھیں"
+ "ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت دیتا ہے۔"
+ "%1$s کو فون کالیں کرنے کی اجازت نہیں ہے"
+ "ویجیٹ کو لوڈ کرنے میں مسئلہ"
+ "ترتیب دیں"
+ "یہ ایک سسٹم ایپ ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"
+ "بلا نام فولڈر"
+ "%1$s غیر فعال ہے"
+
+ - %1$s میں %2$d اطلاعات ہیں
+ - %1$s میں %2$d اطلاع ہے
+
+ "صفحہ %1$d از %2$d"
+ "ہوم اسکرین %1$d از %2$d"
+ "نیا ہوم اسکرین صفحہ"
+ "فولڈر کھولا گیا، %1$d × %2$d"
+ "فولڈر کو بند کرنے کیلئے تھپتھپائیں"
+ "نام کی تبدیلی محفوظ کرنے کیلئے تھپتھپائیں"
+ "فولڈر بند ہو گیا"
+ "فولڈر کا نام تبدیل کر کے %1$s کر دیا گیا"
+ "فولڈر: %1$s"
+ "ویجیٹس"
+ "وال پیپرز"
+ "ہوم ترتیبات"
+ "آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"
+ "ہوم اسکرین گھمانے کی اجازت دیں"
+ "جب فون گھمایا جاتا ہے"
+ "اطلاعاتی ڈاٹس"
+ "آن"
+ "آف"
+ "اطلاعاتی رسائی درکار ہے"
+ "اطلاعاتی ڈاٹس دکھانے کی خاطر %1$s کیلئے ایپ کی اطلاعات آن کریں"
+ "ترتیبات تبدیل کریں"
+ "اطلاعاتی ڈاٹس دکھائیں"
+ "آئیکن کو ہوم اسکرین میں شامل کریں"
+ "نئی ایپس کیلئے"
+ "آئیکن کی شکل تبدیل کریں"
+ "ہوم اسکرین پر"
+ "سسٹم ڈیفالٹ کا استعمال کریں"
+ "مربع"
+ "اسکورکل"
+ "حلقہ"
+ "آنسو کا قطرہ"
+ "آئيکن کی شکل کی تبدیلیاں لاگو ہو رہی ہیں"
+ "نامعلوم"
+ "ہٹائیں"
+ "تلاش کریں"
+ "یہ ایپ انسٹال کردہ نہیں ہے"
+ "اس آئیکن کیلئے ایپ انسٹال کردہ نہیں ہے۔ آپ اسے ہٹا سکتے ہیں یا ایپ کو تلاش کر سکتے اور دستی طور پر اسے انسٹال کر سکتے ہیں۔"
+ "%1$s ڈاؤن لوڈ ہو رہا ہے، %2$s مکمل ہو گیا"
+ "%1$s انسٹال ہونے کا انتظار کر رہی ہے"
+ "%1$s ویجیٹس"
+ "ہوم اسکرین میں شامل کریں"
+ "آئٹم یہاں منتقل کریں"
+ "آئٹم کو ہوم اسکرین میں شامل کر دیا گیا"
+ "آئٹم ہٹا دیا گیا"
+ "آئٹم منتقل کریں"
+ "قطار %1$s کالم %2$s میں منتقل کریں"
+ "پوزیشن %1$s میں منتقل کریں"
+ "پسندیدہ پوزیشن %1$s میں منتقل کریں"
+ "آئٹم منتقل کر دیا گیا"
+ "فولڈر میں شامل کریں: %1$s"
+ "%1$s کے فولڈر میں شامل کریں"
+ "آئٹم فولڈر میں شامل کر دیا گیا"
+ "اس کے ساتھ فولڈر بنائیں: %1$s"
+ "فولڈر بنا دیا گیا"
+ "ہوم اسکرین میں منتقل کریں"
+ "سائز تبدیل کریں"
+ "چوڑائی بڑھائیں"
+ "اونچائی بڑھائیں"
+ "چوڑائی کم کریں"
+ "اونچائی کم کریں"
+ "ویجیٹ کے سائز کو چوڑائی %1$s اونچائی %2$s میں تبدیل کر دیا گیا"
+ "شارٹ کٹس"
+ "%2$s کیلئے %1$d شارٹ کٹس"
+ "%3$s کے %1$d شارٹ کٹس اور %2$d اطلاعات"
+ "برخاست کریں"
+ "اطلاع مسترد ہو گئی"
+ "ذاتی"
+ "دفتری"
+ "دفتری پروفائل"
+ "یہاں دفتری ایپس تلاش کریں"
+ "ہر دفتری ایپ میں ایک بَیج ہوتا ہے اور اسے آپ کی تنظیم محفوظ رکھتی ہے۔ زیادہ آسان رسائی کیلئے ایپس کو اپنی ہوم اسکرین پر منتقل کریں۔"
+ "آپ کی تنظیم کے زیر انتظام"
+ "اطلاعات اور ایپس آف ہیں"
+ "بند کریں"
+ "بند"
+
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index a704fab4ca..7853fd4b36 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -40,13 +40,18 @@
"\"%1$s\" سے مماثل کوئی ایپس نہیں ملیں"
"مزید ایپس تلاش کریں"
"اطلاعات"
+ "ایک شارٹ کٹ منتخب کرنے کیلئے ٹچ کر کے دبائے رکھیں۔"
+ "ایک شارٹ کٹ منتخب کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔"
"اس ہوم اسکرین پر مزید کوئی گنجائش نہیں ہے۔"
"پسندیدہ ٹرے میں مزید کوئی گنجائش نہیں ہے"
"ایپس کی فہرست"
+ "ذاتی ایپس کی فہرست"
+ "دفتری ایپس کی فہرست"
"ہوم"
"ہٹائیں"
"اَن انسٹال کریں"
"ایپ کی معلومات"
+ "انسٹال کریں"
"شارٹ کٹس انسٹال کریں"
"کسی ایپ کو صارف کی مداخلت کے بغیر شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"
"ہوم ترتیبات اور شارٹ کٹس کو پڑھیں"
@@ -59,6 +64,10 @@
"یہ ایک سسٹم ایپ ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"
"بلا نام فولڈر"
"%1$s غیر فعال ہے"
+
+ - %1$s میں %2$d اطلاعات ہیں
+ - %1$s میں %2$d اطلاع ہے
+
"صفحہ %1$d از %2$d"
"ہوم اسکرین %1$d از %2$d"
"نیا ہوم اسکرین صفحہ"
@@ -72,19 +81,19 @@
"وال پیپرز"
"ہوم ترتیبات"
"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"
- "مجموعی جائزہ"
"ہوم اسکرین گھمانے کی اجازت دیں"
"جب فون گھمایا جاتا ہے"
- "موجودہ ڈسپلے ترتیب گھمانے کی اجازت نہیں دیتی"
"اطلاعاتی ڈاٹس"
"آن"
"آف"
"اطلاعاتی رسائی درکار ہے"
"اطلاعاتی ڈاٹس دکھانے کی خاطر %1$s کیلئے ایپ کی اطلاعات آن کریں"
"ترتیبات تبدیل کریں"
+ "اطلاعاتی ڈاٹس دکھائیں"
"آئیکن کو ہوم اسکرین میں شامل کریں"
"نئی ایپس کیلئے"
"آئیکن کی شکل تبدیل کریں"
+ "ہوم اسکرین پر"
"سسٹم ڈیفالٹ کا استعمال کریں"
"مربع"
"اسکورکل"
@@ -99,6 +108,10 @@
"%1$s ڈاؤن لوڈ ہو رہا ہے، %2$s مکمل ہو گیا"
"%1$s انسٹال ہونے کا انتظار کر رہی ہے"
"%1$s ویجیٹس"
+
+
+
+
"ہوم اسکرین میں شامل کریں"
"آئٹم یہاں منتقل کریں"
"آئٹم کو ہوم اسکرین میں شامل کر دیا گیا"
@@ -114,9 +127,6 @@
"اس کے ساتھ فولڈر بنائیں: %1$s"
"فولڈر بنا دیا گیا"
"ہوم اسکرین میں منتقل کریں"
- "اسکرین کو بائیں منتقل کریں"
- "اسکرین کو دائیں منتقل کریں"
- "اسکرین منتقل کر دی گئی"
"سائز تبدیل کریں"
"چوڑائی بڑھائیں"
"اونچائی بڑھائیں"
@@ -124,8 +134,16 @@
"اونچائی کم کریں"
"ویجیٹ کے سائز کو چوڑائی %1$s اونچائی %2$s میں تبدیل کر دیا گیا"
"شارٹ کٹس"
- "%2$s کیلئے %1$d شارٹ کٹس"
- "%3$s کے %1$d شارٹ کٹس اور %2$d اطلاعات"
+ "شارٹ کٹس اور اطلاعات"
"برخاست کریں"
"اطلاع مسترد ہو گئی"
+ "ذاتی"
+ "دفتری"
+ "دفتری پروفائل"
+ "یہاں دفتری ایپس تلاش کریں"
+ "ہر دفتری ایپ میں ایک بَیج ہوتا ہے اور اسے آپ کی تنظیم محفوظ رکھتی ہے۔ زیادہ آسان رسائی کیلئے ایپس کو اپنی ہوم اسکرین پر منتقل کریں۔"
+ "آپ کی تنظیم کے زیر انتظام"
+ "اطلاعات اور ایپس آف ہیں"
+ "بند کریں"
+ "بند"
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
new file mode 100644
index 0000000000..0360a7132a
--- /dev/null
+++ b/res/values-uz-rUZ/strings.xml
@@ -0,0 +1,146 @@
+
+
+
+
+ "Launcher3"
+
+ "Ishga oid"
+ "Ilova o‘rnatilmadi."
+ "Ilova mavjud emas"
+ "Yuklab olingan ilova xavfsiz rejimda o‘chirib qo‘yildi"
+ "Xavfsiz rejimda vidjetlar o‘chirib qo‘yilgan"
+ "Tezkor tugmadan foydalanib bo‘lmaydi"
+ "Bosh ekran"
+ "Maxsus amallar"
+ "Vidjetni tanlash uchun bosib turing."
+ "Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."
+ "%1$d × %2$d"
+ "Eni %1$d, bo‘yi %2$d"
+ "Qo‘lda joylashtirish uchun bosib turing"
+ "Avtomatik chiqarish"
+ "Ilovalarni qidirish"
+ "Ilovalar yuklanmoqda…"
+ "“%1$s” bilan mos hech qanday ilova topilmadi"
+ "Boshqa ilovalarni qidirish"
+ "Bildirishnomalar"
+ "Yorliqni tanlab olish uchun bosib turing."
+ "Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."
+ "Uy ekranida bitta ham xona yo‘q."
+ "Ajratilganlarda birorta ham xona yo‘q"
+ "Ilovalar ro‘yxati"
+ "Shaxsiy ilovalar ro‘yxati"
+ "Ishchi ilovalar ro‘yxati"
+ "Bosh sahifa"
+ "Olib tashlash"
+ "O‘chirib tashlash"
+ "Ilova haqida"
+ "O‘rnatish"
+ "yorliqlar yaratish"
+ "Ilovalarga foydalanuvchidan so‘ramasdan yorliqlar qo‘shishga ruxsat beradi."
+ "Uy sozlamalari va yorliqlarini o‘qish"
+ "Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalarni o‘qish uchun ruxsat beradi."
+ "Uy sozlamalari va yorliqlarini yozish"
+ "Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalrni o‘zgartirish uchun ruxsat beradi."
+ "%1$s ilovasiga qo‘ng‘iroqlarni amalga oshirishga ruxsat berilmagan"
+ "Vidjetni yuklashda muammo"
+ "Sozlash"
+ "Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."
+ "Nomsiz jild"
+ "%1$s ilovasi o‘chirib qo‘yildi"
+
+ - %1$s, %2$d ta bildirishnoma bor
+ - %1$s, %2$d ta bildirishnoma bor
+
+ "%2$ddan %1$d ta sahifa"
+ "Uy ekrani %2$ddan %1$d"
+ "Yangi bosh ekran sahifasi"
+ "Jild ochildi, %1$d ga %2$d"
+ "Jildni yopish uchun ustiga bosing"
+ "O‘zgarishni saqlash uchun ustiga bosing"
+ "Jild yopildi"
+ "Jild nomi %1$sga o‘zgartirildi"
+ "Jild: %1$s"
+ "Vidjetlar"
+ "Fon rasmlari"
+ "Bosh ekran sozlamalari"
+ "Administrator tomonidan o‘chirilgan"
+ "Asosiy ekranni aylantirishga ruxsat berish"
+ "Telefon burilganda"
+ "Bildirishnoma belgilari"
+ "Yoniq"
+ "O‘chiq"
+ "Bildirishnomalarga ruxsat berilmagan"
+ "Bildirishnoma belgilarini ko‘rsatish uchun %1$s ilovasida bildirishnomalarni yoqing"
+ "Sozlamalarni o‘zgartirish"
+ "Bildirishnoma belgilarini ko‘rsatish"
+ "Bosh ekranga ikonka chiqarish"
+ "Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"
+ "Ikonka shaklini o‘zgartirish"
+ "Bosh ekranda"
+ "Standart tizim parametrlaridan foydalanish"
+ "Kvadrat"
+ "Qirralari aylana kvadrat"
+ "Aylana"
+ "Tomchi"
+ "Ikonka shakli o‘zgartirilmoqda"
+ "Noma’lum"
+ "O‘chirish"
+ "Qidirish"
+ "Ushbu ilova o‘rnatilmagan"
+ "Ilova o‘rnatilmagan. Belgini o‘chirib tashlashingiz yoki ilovani topib, uni qo‘lda o‘rnatishingiz mumkin."
+ "%1$s yuklab olinmoqda, %2$s bajarildi"
+ "%1$s ilovasi o‘rnatilishi kutilmoqda"
+ "%1$s vidjetlari"
+ "Bosh ekranga qo‘shish"
+ "Obyektni bu yerga ko‘chirish"
+ "Obyekt bosh ekranga qo‘shildi"
+ "Obyekt o‘chirib tashlandi"
+ "Obyektni ko‘chirib o‘tkazish"
+ "%1$s %2$s katakka ko‘chirib o‘tkazish"
+ "%1$s-joyga ko‘chirib o‘tkazish"
+ "Sevimlilarga (%1$s) ko‘chirib o‘tkazish"
+ "Element ko‘chirib o‘tkazildi"
+ "%1$s jildiga qo‘shish"
+ "%1$s ilovasi bor jildga qo‘shish"
+ "Element jildga qo‘shildi"
+ "%1$s bilan jild yaratish"
+ "Jild yaratildi"
+ "Bosh ekranga ko‘chirish"
+ "O‘lchamini o‘zgartirish"
+ "Enini uzaytirish"
+ "Bo‘yini uzaytirish"
+ "Enini kichraytirish"
+ "Bo‘yini kichraytirish"
+ "Vidjetning eni %1$s, bo‘yi %2$s qilib o‘zgartirildi"
+ "Tezkor tugmalar"
+ "%2$s ilovasi uchun %1$d ta tezkor tugma"
+ "%3$s ilovasi uchun %1$d ta yorliq va %2$d ta bildirishnoma"
+ "Yopish"
+ "Bildirishnoma yopildi"
+ "Shaxsiy"
+ "Ishchi"
+ "Ishchi profil"
+ "Ishga oid ilovalarni shu yerdan topish mumkin"
+ "Nishonga ega har bir ishga oid ilova tashkilotingiz tomonidan himoyalanadi. Ishga oid ilovalarga osonroq kirish uchun ularni bosh ekranga chiqaring."
+ "Tashkilotingiz tomonidan boshqariladi"
+ "Bildirishnomalar va ilovalar faol emas"
+ "Yopish"
+ "Yopiq"
+
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 7e31889138..287ec09f76 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -40,13 +40,18 @@
"“%1$s” bilan mos hech qanday ilova topilmadi"
"Boshqa ilovalarni qidirish"
"Bildirishnomalar"
+ "Yorliqni tanlab olish uchun bosib turing."
+ "Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."
"Uy ekranida bitta ham xona yo‘q."
"Ajratilganlarda birorta ham xona yo‘q"
"Ilovalar ro‘yxati"
+ "Shaxsiy ilovalar ro‘yxati"
+ "Ishchi ilovalar ro‘yxati"
"Bosh sahifa"
"Olib tashlash"
"O‘chirib tashlash"
"Ilova haqida"
+ "O‘rnatish"
"yorliqlar yaratish"
"Ilovalarga foydalanuvchidan so‘ramasdan yorliqlar qo‘shishga ruxsat beradi."
"Uy sozlamalari va yorliqlarini o‘qish"
@@ -59,6 +64,10 @@
"Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."
"Nomsiz jild"
"%1$s ilovasi o‘chirib qo‘yildi"
+
+ - %1$s, %2$d ta bildirishnoma bor
+ - %1$s, %2$d ta bildirishnoma bor
+
"%2$ddan %1$d ta sahifa"
"Uy ekrani %2$ddan %1$d"
"Yangi bosh ekran sahifasi"
@@ -70,21 +79,21 @@
"Jild: %1$s"
"Vidjetlar"
"Fon rasmlari"
- "Home sozlamalari"
+ "Bosh ekran sozlamalari"
"Administrator tomonidan o‘chirilgan"
- "Umumiy ko‘rinish"
"Asosiy ekranni aylantirishga ruxsat berish"
"Telefon burilganda"
- "Ekran sozlamalariga ko‘ra uni aylantirib bo‘lmaydi"
- "Bildirishnoma nuqtalari"
+ "Bildirishnoma belgilari"
"Yoniq"
"O‘chiq"
"Bildirishnomalarga ruxsat berilmagan"
- "Bildirishnoma nuqtalarini ko‘rsatish uchun %1$s ilovasida bildirishnomalarni yoqing"
+ "Bildirishnoma belgilarini ko‘rsatish uchun %1$s ilovasida bildirishnomalarni yoqing"
"Sozlamalarni o‘zgartirish"
- "Bosh ekranga ikonka qo‘shish"
+ "Bildirishnoma belgilarini ko‘rsatish"
+ "Bosh ekranga ikonka chiqarish"
"Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"
"Ikonka shaklini o‘zgartirish"
+ "Bosh ekranda"
"Standart tizim parametrlaridan foydalanish"
"Kvadrat"
"Qirralari aylana kvadrat"
@@ -99,6 +108,8 @@
"%1$s yuklab olinmoqda, %2$s bajarildi"
"%1$s ilovasi o‘rnatilishi kutilmoqda"
"%1$s vidjetlari"
+ "Vidjetlar ro‘yxati"
+ "Vidjetlar ro‘yxati yopildi"
"Bosh ekranga qo‘shish"
"Obyektni bu yerga ko‘chirish"
"Obyekt bosh ekranga qo‘shildi"
@@ -114,9 +125,6 @@
"%1$s bilan jild yaratish"
"Jild yaratildi"
"Bosh ekranga ko‘chirish"
- "Ekranni chapga siljitish"
- "Ekranni o‘ngga siljitish"
- "Ekran siljitildi"
"O‘lchamini o‘zgartirish"
"Enini uzaytirish"
"Bo‘yini uzaytirish"
@@ -124,8 +132,16 @@
"Bo‘yini kichraytirish"
"Vidjetning eni %1$s, bo‘yi %2$s qilib o‘zgartirildi"
"Tezkor tugmalar"
- "%2$s ilovasi uchun %1$d ta tezkor tugma"
- "%3$s ilovasi uchun %1$d ta yorliq va %2$d ta bildirishnoma"
+ "Yorliqlar va bildirishnomalar"
"Yopish"
"Bildirishnoma yopildi"
+ "Shaxsiy"
+ "Ishchi"
+ "Ishchi profil"
+ "Ishga oid ilovalarni shu yerdan topish mumkin"
+ "Nishonga ega har bir ishga oid ilova tashkilotingiz tomonidan himoyalanadi. Ishga oid ilovalarga osonroq kirish uchun ularni bosh ekranga chiqaring."
+ "Tashkilotingiz tomonidan boshqariladi"
+ "Bildirishnomalar va ilovalar faol emas"
+ "Yopish"
+ "Yopiq"
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 83e1ceabaa..06278f5cf7 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -40,13 +40,18 @@
"Không tìm thấy ứng dụng nào phù hợp với \"%1$s\""
"Tìm kiếm thêm ứng dụng"
"Thông báo"
+ "Chạm và giữ để chọn lối tắt."
+ "Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh."
"Không còn chỗ trên Màn hình chính này."
"Không còn chỗ trong khay Mục yêu thích"
"Danh sách ứng dụng"
+ "Danh sách ứng dụng cá nhân"
+ "Danh sách ứng dụng công việc"
"Màn hình chính"
"Xóa"
"Gỡ cài đặt"
"Thông tin ứng dụng"
+ "Cài đặt"
"cài đặt lối tắt"
"Cho phép ứng dụng thêm lối tắt mà không cần sự can thiệp của người dùng."
"đọc cài đặt và lối tắt trên Màn hình chính"
@@ -59,6 +64,10 @@
"Đây là ứng dụng hệ thống và không thể gỡ cài đặt."
"Thư mục chưa đặt tên"
"Đã vô hiệu hóa %1$s"
+
+ - %1$s, có %2$d thông báo
+ - %1$s, có %2$d thông báo
+
"Trang %1$d / %2$d"
"Màn hình chính %1$d / %2$d"
"Trang màn hình chính mới"
@@ -70,21 +79,21 @@
"Thư mục: %1$s"
"Tiện ích con"
"Hình nền"
- "Cài đặt trang chủ"
+ "Cài đặt màn hình chính"
"Bị tắt bởi quản trị viên của bạn"
- "Tổng quan"
"Cho phép xoay Màn hình chính"
"Khi xoay điện thoại"
- "Cài đặt Hiển thị hiện tại không cho phép xoay"
"Dấu chấm thông báo"
"Đang bật"
"Đã tắt"
"Cần quyền truy cập thông báo"
"Để hiển thị Dấu chấm thông báo, hãy bật thông báo ứng dụng cho %1$s"
"Thay đổi cài đặt"
+ "Hiển thị dấu chấm thông báo"
"Thêm biểu tượng vào màn hình chính"
"Cho ứng dụng mới"
"Thay đổi hình dạng biểu tượng"
+ "trên Màn hình chính"
"Sử dụng mặc định của hệ thống"
"Hình vuông"
"Hình vuông cạnh bo tròn"
@@ -99,6 +108,8 @@
"Đang tải xuống %1$s, %2$s hoàn tất"
"Đang chờ cài đặt %1$s"
"Tiện ích của %1$s"
+ "Danh sách tiện ích"
+ "Đã đóng danh sách tiện ích"
"Thêm vào màn hình chính"
"Di chuyển mục vào đây"
"Đã thêm mục vào màn hình chính"
@@ -114,9 +125,6 @@
"Tạo thư mục bằng: %1$s"
"Đã tạo thư mục"
"Di chuyển đến màn hình chính"
- "Di chuyển màn hình sang trái"
- "Di chuyển màn hình sang phải"
- "Đã di chuyển màn hình"
"Đổi kích thước"
"Tăng chiều rộng"
"Tăng chiều cao"
@@ -124,8 +132,16 @@
"Giảm chiều cao"
"Đã đổi kích thước tiện ích thành chiều rộng %1$s chiều cao %2$s"
"Lối tắt"
- "%1$d phím tắt cho %2$s"
- "%1$d phím tắt và %2$d thông báo cho %3$s"
+ "Phím tắt và thông báo"
"Loại bỏ"
"Đã loại bỏ thông báo"
+ "Cá nhân"
+ "Cơ quan"
+ "Hồ sơ công việc"
+ "Tìm ứng dụng công việc tại đây"
+ "Mỗi ứng dụng công việc đều có một huy hiệu và được tổ chức của bạn bảo mật. Bạn có thể di chuyển ứng dụng đến Màn hình chính để truy cập dễ dàng hơn."
+ "Do tổ chức của bạn quản lý"
+ "Thông báo và ứng dụng đang tắt"
+ "Đóng"
+ "Đã đóng"
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index bef12fb61b..640aa0e2f0 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -40,13 +40,18 @@
"未找到与“%1$s”相符的应用"
"搜索更多应用"
"通知"
+ "触摸并按住快捷方式即可选择快捷方式。"
+ "点按两次并按住快捷方式即可选择快捷方式,您也可以使用自定义操作。"
"此主屏幕上已没有空间。"
"收藏栏已满"
"应用列表"
+ "个人应用列表"
+ "工作应用列表"
"主屏幕"
"移除"
"卸载"
"应用信息"
+ "安装"
"安装快捷方式"
"允许应用自行添加快捷方式。"
"读取主屏幕设置和快捷方式"
@@ -59,6 +64,10 @@
"这是系统应用,无法卸载。"
"未命名文件夹"
"已停用%1$s"
+
+ - %1$s,有 %2$d 个通知
+ - %1$s,有 %2$d 个通知
+
"第%1$d页,共%2$d页"
"主屏幕:第%1$d屏,共%2$d屏"
"主屏幕新页面"
@@ -72,19 +81,19 @@
"壁纸"
"主屏幕设置"
"已被您的管理员停用"
- "概览"
"允许旋转主屏幕"
"手机旋转时"
- "当前的显示设置不允许旋转设备"
"通知圆点"
"开启"
"关闭"
"需要获取通知使用权"
"要显示通知圆点,请开启%1$s的应用通知功能"
"更改设置"
+ "显示通知圆点"
"将图标添加到主屏幕"
"适用于新应用"
"更改图标形状"
+ "在主屏幕上"
"使用系统默认设置"
"方形"
"方圆形"
@@ -99,6 +108,8 @@
"正在下载%1$s,已完成 %2$s"
"%1$s正在等待安装"
"%1$s微件"
+ "微件列表"
+ "微件列表已关闭"
"添加到主屏幕"
"将项目移至此处"
"已将项目添加到主屏幕"
@@ -114,9 +125,6 @@
"创建“%1$s”文件夹"
"文件夹已创建"
"移至主屏幕"
- "将屏幕向左移动"
- "将屏幕向右移动"
- "屏幕已移动"
"调整大小"
"增加宽度"
"增加高度"
@@ -124,8 +132,16 @@
"减小高度"
"微件尺寸已调整为:宽度 %1$s,高度 %2$s"
"快捷方式"
- "%2$s有 %1$d 个快捷方式"
- "%3$s的 %1$d 个快捷方式和 %2$d 条通知"
+ "快捷方式和通知"
"关闭"
"已关闭通知"
+ "个人"
+ "工作"
+ "工作资料"
+ "请在此处查找工作应用"
+ "每个工作应用均有一个徽标,并由贵单位负责确保其安全。请将工作应用移到主屏幕,以便轻松访问。"
+ "由贵单位管理"
+ "通知和应用均已关闭"
+ "关闭"
+ "已关闭"
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 7ac5553957..5a8c6caec6 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -40,13 +40,18 @@
"找不到與「%1$s」相符的應用程式"
"搜尋更多應用程式"
"通知"
+ "按住捷徑即可選取。"
+ "撳兩下之後撳住,就可以揀選捷徑或者用自訂嘅操作。"
"主畫面已無空間。"
"我的收藏寄存區沒有足夠空間"
"應用程式清單"
+ "個人應用程式清單"
+ "工作應用程式清單"
"主畫面"
"移除"
"解除安裝"
"應用程式資料"
+ "安裝"
"安裝捷徑"
"允許應用程式無需使用者許可也可新增捷徑。"
"讀取主畫面的設定和捷徑"
@@ -59,6 +64,10 @@
"這是系統應用程式,無法將其解除安裝。"
"未命名的資料夾"
"「%1$s」已停用"
+
+ - %1$s,有 %2$d 項通知
+ - %1$s,有 %2$d 項通知
+
"第 %1$d 頁,共 %2$d 頁"
"主畫面 %1$d,共 %2$d 個"
"新主畫面頁面"
@@ -70,21 +79,21 @@
"資料夾:%1$s"
"小工具"
"桌布"
- "Home 設定"
+ "主螢幕設定"
"已由您的管理員停用"
- "概覽"
"允許主畫面旋轉"
"當手機旋轉時"
- "「目前顯示屏」設定不允許旋轉"
"通知圓點"
"開啟"
"關閉"
"需要獲取通知存取權"
"如要顯示「通知圓點」,請開啟「%1$s」的應用程式通知功能"
"變更設定"
+ "顯示通知圓點"
"將圖示加到主畫面"
"適用於新安裝的應用程式"
"變更圖示形狀"
+ "在主畫面上"
"使用系統預設設定"
"正方形"
"方圓形"
@@ -99,6 +108,8 @@
"正在下載 %1$s,已完成 %2$s"
"正在等待安裝 %1$s"
"%1$s小工具"
+ "小工具清單"
+ "已經關閉嘅小工具清單"
"新增至主畫面"
"移動項目至這裡"
"已將項目加入至主畫面"
@@ -114,9 +125,6 @@
"使用以下項目建立資料夾:%1$s"
"已建立資料夾"
"移動至主畫面"
- "向左移動螢幕"
- "向右移動螢幕"
- "已移動螢幕"
"重新調整大小"
"增加闊度"
"增加高度"
@@ -124,8 +132,16 @@
"減少高度"
"已調整小工具的大小至闊 %1$s 高 %2$s"
"捷徑"
- "「%2$s」嘅 %1$d 個捷徑"
- "「%3$s」嘅 %1$d 個捷徑同 %2$d 個通知"
+ "捷徑同通知"
"關閉"
"關閉咗通知"
+ "個人"
+ "商務"
+ "工作設定檔"
+ "請在此處尋找工作應用程式"
+ "每個工作應用程式都有一個徽章,並由您的機構負責保持安全。您可以將工作應用程式移至主畫面,以便輕鬆存取。"
+ "由您的機構管理"
+ "通知和應用程式已關閉"
+ "關閉"
+ "已關閉"
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index e0c4c9973e..4d37cdd20a 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -40,13 +40,18 @@
"找不到與「%1$s」相符的應用程式"
"搜尋更多應用程式"
"通知"
+ "按住捷徑即可選取。"
+ "輕觸兩下並按住捷徑即可選取,你也可以使用自訂動作。"
"這個主螢幕已無空間。"
"「我的最愛」匣已無可用空間"
"應用程式清單"
+ "個人應用程式清單"
+ "辦公應用程式清單"
"主螢幕"
"移除"
"解除安裝"
"應用程式資訊"
+ "安裝"
"安裝捷徑"
"允許應用程式自動新增捷徑。"
"讀取主螢幕的設定和捷徑"
@@ -59,6 +64,10 @@
"這是系統應用程式,不可解除安裝。"
"未命名的資料夾"
"已停用 %1$s"
+
+ - %1$s,有 %2$d 則通知
+ - %1$s,有 %2$d 則通知
+
"第 %1$d 頁,共 %2$d 頁"
"主螢幕:第 %1$d 頁,共 %2$d 頁"
"新的主畫面頁面"
@@ -72,19 +81,19 @@
"桌布"
"Home 設定"
"已由你的管理員停用"
- "總覽"
"允許旋轉主螢幕"
"當手機旋轉時"
- "目前的顯示設定不允許旋轉畫面"
"通知圓點"
"已啟用"
"已停用"
"需要取得通知存取權"
"如要顯示通知圓點,請開啟「%1$s」的應用程式通知功能"
"變更設定"
+ "顯示通知圓點"
"將圖示加到主螢幕"
"適用於新安裝的應用程式"
"變更圖示形狀"
+ "在主螢幕上"
"使用系統預設值"
"正方形"
"方圓形"
@@ -99,6 +108,8 @@
"正在下載「%1$s」,已完成 %2$s"
"正在等待安裝「%1$s」"
"「%1$s」小工具"
+ "小工具清單"
+ "已關閉小工具清單"
"新增至主畫面"
"將項目移至這裡"
"已將項目新增到主畫面"
@@ -114,9 +125,6 @@
"建立「%1$s」資料夾"
"已建立資料夾"
"移至主畫面"
- "將畫面往左移"
- "將畫面往右移"
- "已移動畫面"
"調整大小"
"增加寬度"
"增加高度"
@@ -124,8 +132,16 @@
"減少高度"
"已將小工具的寬度和高度分別調整為 %1$s 和 %2$s"
"捷徑"
- "「%2$s」有 %1$d 個捷徑"
- "%1$d 個捷徑和 %2$d 則「%3$s」通知"
+ "捷徑和通知"
"關閉"
"已關閉通知"
+ "個人"
+ "公司"
+ "工作資料夾"
+ "在這裡尋找辦公應用程式"
+ "每個辦公應用程式都有徽章,並由貴機構負責管理及確保其安全。請將辦公應用程式移至主螢幕以便輕鬆存取。"
+ "由貴機構所管理"
+ "已關閉通知和應用程式"
+ "關閉"
+ "已關閉"
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index ef6fdeb10a..8e3e5abc60 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -40,13 +40,18 @@
"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"%1$s\""
"Sesha izinhlelo zokusebenza eziningi"
"Izaziso"
+ "Thinta futhi ubambe ukuze ukhethe isinqamuleli."
+ "Thepha kabili uphinde ubambe ukuze uphakamise isinqamuleli noma usebenzise izenzo zangokwezifiso."
"Asisekho isikhala kulesi sikrini Sasekhaya."
"Asisekho isikhala kwitreyi lezintandokazi"
"Uhlu lwezinhlelo zokusebenza"
+ "Uhlu lwezinhlelo zokusebenza zomuntu siqu"
+ "Uhlu lwezinhlelo zokusebenza zomsebenzi"
"Ikhaya"
"Susa"
"Khipha"
"Ulwazi lohlelo lokusebenza"
+ "Faka"
"faka izinqamuleli"
"Ivumela uhlelo lokusebenza ukufaka izinqamuleli ngaphandle kokungenelela komsebenzisi."
"funda izilungiselelo zokuthi Ikhaya nezinqamuleli"
@@ -59,6 +64,10 @@
"Lolu uhlelo lokusebenza lwesistimu futhi alikwazi ukukhishwa."
"Ifolda engenagama"
"Kukhutshaziwe %1$s"
+
+ - %1$s, inezaziso ezingu-%2$d
+ - %1$s, inezaziso ezingu-%2$d
+
"Ikhasi elingu-%1$d kwangu-%2$d"
"Isikrini sasekhaya esingu-%1$d se-%2$d"
"Ikhasi elisha lesikrini sasekhaya"
@@ -72,19 +81,19 @@
"Izithombe zangemuva"
"Izilungiselelo zasekhaya"
"Kukhutshazwe umlawuli wakho"
- "Ukubuka konke"
"Vumela ukuphendukiswa kwesikrini sasekhaya"
"Uma ifoni iphendukiswa"
- "Isilungiselelo sesiboniso samanje asivumeli ukuzungezisa"
"Amachashazi esaziso"
"Kuvuliwe"
"Kuvaliwe"
"Ukufinyelela izaziso kuyadingeka"
"Ukuze ubonisa amcashazi esaziso, vula izaziso zohlelo lokusebenza ze-%1$s"
"Shintsha izilungiselelo"
+ "Bonisa amacashazi esaziso"
"Engeza isithonjana eskrinini sasekhaya"
"Kwezinhlelo zokusebenza ezintsha"
"Shintsha isimo sesithonjana"
+ "kusikrini sasekhaya"
"Sebenzisa okuzenzakalelayo kwesistimu"
"Isikwele"
"I-Squircle"
@@ -99,6 +108,8 @@
"I-%1$s iyalandwa, %2$s kuqediwe"
"%1$s ilinde ukufakwa"
"%1$s amawijethi"
+ "Uhlu lwamawijethi"
+ "Uhlu lwamawijethi luvaliwe"
"Faka kusikrini sasekhaya"
"Hambisa into lapha"
"Into ingezwe kusikrini sasekhaya"
@@ -114,9 +125,6 @@
"Dala ifolda nge-: %1$s"
"Ifolda idaliwe"
"Hambisa kusikrini sasekhaya"
- "Hambisa isikrini kwesokunxele"
- "Hambisa isikrini kwesokudla"
- "Isikrini sihanjisiwe"
"Shintsha usayizi"
"Khuphula ububanzi"
"Khuphula ubude"
@@ -124,8 +132,16 @@
"Nciphisa ubude"
"Iwijethi inikezwe usayizi omusha ngobubanzi obungu-%1$s ubude obungu-%2$s"
"Izinqamuleli"
- "%1$d izinqamuleli ze-%2$s"
- "%1$d izinqamuleli nezaziso ezingu-%2$d ze-%3$s"
+ "Izinqamuleli nezaziso"
"Cashisa"
"Isaziso sicashisiwe"
+ "Okomuntu siqu"
+ "Umsebenzi"
+ "Iphrofayela yomsebenzi"
+ "Thola izinhlelo zokusebenza lapha"
+ "Uhlo lokusebenza ngalunye lomsebenzi linebheji futhi igcinwa iphephile inhlangano yakho. Hambisa izinhlelo zokusebenza esikrinini sakho sasekhaya ngokufinyelela okulula."
+ "Kuphethwe inhlangano yakho"
+ "Izaziso nezinhlelo zokusebenza kuvaliwe"
+ "Vala"
+ "Kuvaliwe"
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 5aee715b67..30091a5f77 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -20,6 +20,7 @@
+
@@ -44,7 +45,6 @@
-
@@ -63,13 +63,6 @@
-
-
-
-
-
-
@@ -98,10 +91,6 @@
-
-
-
-
@@ -112,8 +101,6 @@
-
-
@@ -144,4 +131,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values/colors.xml b/res/values/colors.xml
index b44a31e40d..eb207af1eb 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -32,8 +32,6 @@
#757575
- #1DE9B6
- #1DE9B6
#E0E0E0
#FFFFFF
diff --git a/res/values/config.xml b/res/values/config.xml
index 10b612ba2d..d5bb131eff 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,8 +1,4 @@
-
-
- 22
-
false
false
@@ -45,26 +41,8 @@
-
- 30
- 100
- 250
-
90
-
- 70
-
-
- 220
- 320
- 300
- 60
-
-
- 17
50
@@ -86,9 +64,7 @@
500
- 120
200
- 60
30
@@ -113,23 +89,36 @@
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
150
@@ -139,7 +128,7 @@
-
+
@@ -147,6 +136,7 @@
+
@@ -154,4 +144,9 @@
+
+
+ 6
+ 12
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b1f9d63797..07e0b04ddd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -15,17 +15,13 @@
-->
-
+
+ 4dp
+
+
8dp
- 32dp
1dp
- 0dp
- 0dp
8dp
- 80dp
- 120dp
- 80dp
- 25dp
8dp
8dp
@@ -39,22 +35,19 @@
8dp
2dp
80dp
+ 0dp
- 0dp
- 0dp
- 0dp
- 0dp
- 0dp
- 0dp
-
+
+ 8dp
+ 8dp
+ 4dp
+ 24dp
48dp
- 20dp
- 14dp
+ 20dp
- 8dp
13dp
24dp
@@ -82,15 +75,18 @@
0dp
48dp
- 60dp
+ 30dp
40dp
144dp
700dp
475dp
- 2dp
- 1dp
- 13dp
- 18dp
+ 50dp
+ 2dp
+ 36dp
+ 16dp
+ 20dp
+ 12dp
+ 1dp
3dp
@@ -141,8 +137,6 @@
1dp
-
- 10dp
8dp
9dp
@@ -180,6 +174,7 @@
16dp
10dp
16dp
+ 4dp
10dp
8dp
-2dp
@@ -187,10 +182,6 @@
28dp
24dp
-
- 23dp
-
- 19dp
2dp
56dp
@@ -204,12 +195,8 @@
12dp
-
- 0dp
- 3dp
-
- 12dp
+ 8dp
16dp
12dp
@@ -227,14 +214,13 @@
18dp
52dp
- 2dp
18dp
19dp
0.5dp
70dp
-
-
- 24dp
+
+ 24dp
+ 32dp
diff --git a/res/values/drawables.xml b/res/values/drawables.xml
index fea17b1530..1367174b1b 100644
--- a/res/values/drawables.xml
+++ b/res/values/drawables.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
- @drawable/ic_info_no_shadow
+ @drawable/ic_setting
@drawable/ic_remove_no_shadow
@drawable/ic_uninstall_no_shadow
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1197b1cf2c..7bc11c3be1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -72,6 +72,11 @@
Notifications
+
+ Touch & hold to pick up a shortcut.
+
+ Double-tap & hold to pick up a shortcut or use custom actions.
+
No more room on this Home screen.
@@ -80,6 +85,9 @@
Apps list
+ Personal apps list
+ Work apps list
+
Home
@@ -90,6 +98,8 @@
Uninstall
App info
+
+ Install
@@ -130,6 +140,11 @@
Disabled %1$s
+
+
+ - %1$s, has %2$d notification
+ - %1$s, has %2$d notifications
+
@@ -162,16 +177,12 @@
Home settings
Disabled by your admin
-
- Overview
Allow Home screen rotation
When phone is rotated
-
- Current Display setting doesn\'t permit rotation
Notification dots
@@ -184,6 +195,8 @@
To show Notification Dots, turn on app notifications for %1$s
Change settings
+
+ Show notification dots
Add icon to Home screen
@@ -192,6 +205,8 @@
Change icon shape
+
+ on Home screen
Use system default
@@ -229,6 +244,11 @@
%1$s widgets
+
+ Widgets list
+
+ Widgets list closed
+
Add to Home screen
@@ -275,15 +295,6 @@
Move to Home screen
-
- Move screen to left
-
-
- Move screen to right
-
-
- Screen moved
-
Resize
@@ -304,11 +315,9 @@
Shortcuts
-
-
- %1$d shortcuts for %2$s
-
- %1$d shortcuts and %2$d notifications for %3$s
+
+ Shortcuts and notifications
+
Dismiss
@@ -316,4 +325,23 @@
Notification dismissed
+
+ Personal
+
+
+ Work
+
+
+ Work profile
+
+ Find work apps here
+
+ Each work app has a badge and is kept secure by your organization. Move apps to your Home screen for easier access.
+
+ Managed by your organization
+
+ Notifications and apps are off
+ Close
+ Closed
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8129e810f5..31cbaa11af 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -25,11 +25,11 @@
- true
- true
- #FF757575
- - @layout/search_container_all_apps
-
+
+
- 0
@@ -136,13 +148,6 @@
-